Sunday, March 18, 2012

Activate Any Window With API

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 LongPrivate 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 IfEnd Function

You can now activate the Word window with this simple code: If fActivateWindowClass(gcClassnameMSWord) Then ' succeeded, do what you willElse ' failed, handle with graceEnd 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


View the original article here

No comments:

Post a Comment