Activate Any Window With API

Level:
Level2

One of the most common questions I've seen posted on newsgroups and online services involves activating another Windows application. The VB AppActivate statement falls hopelessly short of being truly useful since the window title of an application can change without notice. A much more reliable means of activating another application is by using the window class name. It's much more reliable because the class name of a window will not change once the application has been installed.

So, you ask, how do I get the class name of another application? While many will tell you that you need some sort of "spy" program, this is completely unnecessary. You can find the window class name for any application by running a few lines of code in the debug window. This is a one-time-only procedure.

Disclaimer: This will not help you activate a program written in VB. All VB form windows have the class name "ThunderForm". You'll have to revert to the old method of using the window text, or if the program is your own, make it an OLE server and provide a public Activate method. You can also check out this article in the Microsoft Knowledge Base:

How to Get a Window Handle Without Specifying an Exact Title
Article ID: Q113475

That being said, here's what you do:

Create a blank new module or use an existing module.

Place the following in the declarations section:

Private Declare Function FindWindow Lib "user32" _
   Alias "FindWindowA" _
   (ByVal lpClassName As String, _
   ByVal lpWindowName As String) As Long

Private Declare Function GetClassName Lib "user32" _
   Alias "GetClassNameA" _
   (ByVal hWnd As Long, _
   ByVal lpClassName As String, _
   ByVal nMaxCount As Long) As Long

Enter the following procedure:

Public Sub GetClassNameFromTitle()
   Dim sInput As String
   Dim hWnd As Long
   Dim lpClassName As String
   Dim nMaxCount As Long
   Dim lresult As Long
   ' pad the return buffer for GetClassName
   nMaxCount = 256
   lpClassName = Space(nMaxCount)
   ' Note: must be an exact match
   sInput = InputBox("Enter the exact window title:")
   ' No validation is done as this is a debug window utility
   hWnd = FindWindow(vbNullString, sInput)
   ' Get the class name of the window, again, no validation
   lresult = GetClassName(hWnd, lpClassName, nMaxCount)
   Debug.Print "Window: " & sInput
   Debug.Print "Class name: " & Left$(lpClassName, lresult)
End Sub

Run GetClassNameFromTitle in the debug window. If you enter the window title correctly, the class name will be printed in the debug window.

Once you have the window class name, you can always get a window handle by using FindWindow with the class name and vbNullString. For example:

hWnd = FindWindow("OpusApp", vbNullString)

...will find the hWnd for the Microsoft Word window. Actually, I typically will code constants for the applications I will need to activate on a regular basis.

Public Constant gcClassnameMSWord = "OpusApp"

I also use a wrapper function for the whole process:

Public Function fActivateWindowClass(psClassname As String) As Boolean
   Dim hWnd As Long
   hWnd = FindWindow(psClassname, vbNullString)
   If hWnd > 0 Then
      ' ShowWindow returns True if the window was previously hidden. 
      ' I don't care so I use the sub style
      ' ShowWindow and SW_SHOW declared elsewhere
      ' SW_SHOW will display the window in its current size and position
      Call ShowWindow hWnd, SW_SHOW
      fActivateWindowClass = True
   Else
      ' FindWindow failed, return False
      fActivateWindowClass = False
   End If
End Function

You can now activate the Word window with this simple code:

If fActivateWindowClass(gcClassnameMSWord) Then
   ' succeeded, do what you will
Else
   ' failed, handle with grace
End if

This procedure could easily be extended to shell the application if FindWindow fails. That is left as an exercise for you.

Originally written by Joe Garrick

If you enjoyed this post, subscribe for updates (it's free)

Private Declare Function

Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long

Private Declare Function GetClassName Lib "user32" _
Alias "GetClassNameA" _
(ByVal hWnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Enter the following procedure:

Public Sub GetClassNameFromTitle()
Dim sInput As String
Dim hWnd As Long
Dim lpClassName As String
Dim nMaxCount As Long
Dim lresult As Long
' pad the return buffer for GetClassName
nMaxCount = 256
lpClassName = Space(nMaxCount)
' Note: must be an exact match
sInput = InputBox("Enter the exact window title:")
' No validation is done as this is a debug window utility
hWnd = FindWindow(vbNullString, sInput)
' Get the class name of the window, again, no validation
lresult = GetClassName(hWnd, lpClassName, nMaxCount)
Debug.Print "Window: " & sInput
Debug.Print "Class name: " & Left$(lpClassName, lresult)
End Sub

The ShowWindow API is missing from the Example

The 'ShowWindow' API is missing from the Example. Here's the full code I worked out with the ShowWindow API That Works VB6. Also in the original example the variable SW_SHOW is not set. This will cause an error. I set SW_SHOW as a constant at the top of the module. The value 9 activates the window and shows it if minimized.

See: http://support.microsoft.com/kb/104710
for more info and a list of application class names.

'''''''''''''''''''''''''''''''' START CODE ''''''''''''''''''''''''''''''''''''''

' Windows API Declarations
Private Declare Function ShowWindow Lib "User32" _
(ByVal hWnd As Long, ByVal nCmdShow As Integer) As Integer

Private Declare Function FindWindow Lib "User32" _
Alias "FindWindowA" _
(ByVal lpclassname As String, _
ByVal lpWindowName As String) As Long

Private Declare Function GetClassName Lib "User32" _
Alias "GetClassNameA" _
(ByVal hWnd As Long, _
ByVal lpclassname As String, _
ByVal nMaxCount As Long) As Long

Const SW_SHOW = 9

' Enter the following procedure:

Public Sub GetClassNameFromTitle()
Dim sInput As String
Dim hWnd As Long
Dim lpclassname As String
Dim nMaxCount As Long
Dim lresult As Long
' pad the return buffer for GetClassName
nMaxCount = 256
lpclassname = Space(nMaxCount)
' Note: must be an exact match
sInput = "Microsoft Word" ' InputBox("Enter the exact window title:")
' No validation is done as this is a debug window utility
hWnd = FindWindow(vbNullString, sInput)
' Get the class name of the window, again, no validation
lresult = GetClassName(hWnd, lpclassname, nMaxCount)
' Debug.Print "Window: " & sInput
' Debug.Print "Class name: " & Left$(lpClassName, lresult)

Call fActivateWindowClass(lpclassname)
End Sub

Public Function fActivateWindowClass(psClassname As String) As Boolean
Dim hWnd As Long
hWnd = FindWindow(psClassname, vbNullString)
If hWnd > 0 Then
' ShowWindow returns True if the window was previously hidden.
' I don't care so I use the sub style
' ShowWindow and SW_SHOW declared elsewhere
' SW_SHOW will display the window in its current size and position
' SW_SHOW = 1
Call ShowWindow(hWnd, SW_SHOW)
fActivateWindowClass = True
Else
' FindWindow failed, return False
fActivateWindowClass = False
End If
End Function

Sub CheckWindowOpen()
' You can now activate the Word window with this simple code:
If fActivateWindowClass(gcClassnameMSWord) Then
' succeeded, do what you will
Else
' failed, handle with grace
End If

End Sub

' You can also call the fActivateWindowClass Function directly if you know the Applicaiton Class Name
Sub WordAppActivate()

x = fActivateWindowClass("opusapp")

End Sub

this is vb6.0 not vb.net

this is vb6.0 not vb.net

Maybe...

Because it's in a VB6 tutorial site?

How can i get classname from the handle of active window?

Am new to VB.Net coding.
I have the handle for the active window. But i need the classname. My code looks somewhat like this.

Public Class Form1
Declare Function GetForegroundWindow Lib "user32.dll" () As Int32
Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hwnd As Int32, ByVal lpwindowtext As String, ByVal nmaxcount As Int32) As Int32

Public Structure Window
Public Handle As IntPtr
Public Text As String
End Structure

Public Function GetWindowText() As Window
Dim title As String
title = New String(Chr(0), 100)
Dim titleLength As Integer
titleLength = GetWindowText(GetForegroundWindow(), title, 255)
titleLength = title.Length
Dim w As New Window
w.Text = title.ToString()
w.Handle = GetForegroundWindow()
Return w
End Function

So i have the handle. But how can i get the classname from that hadle?
Please help me...... Its important and i dont hav much time.
Thanks in advance.