VB3 How to Get Window Handle Without Specifying Exact Title

ID: Q113475


The information in this article applies to:


SUMMARY

The Visual Basic AppActivate command can only activate a window if you know the exact window title. Similarly, the Windows FindWindow function can only find a window handle if you know the exact window title.

This article demonstrates how to search for a window that has a title that is like the title you specify -- but not an exact match. The sample code searches through the available windows, comparing the window titles to a pattern by using the Visual Basic Like operator. You can also use the sample code to find a window based on its class name or ID. This can be extremely helpful when you need to send keystrokes to other Applications.


MORE INFORMATION

FindWindowLike Function

The sample code provides a find window function named FindWindowLike. FindWindowLike does a recursive search for windows matching the description you give it. After completing the search, FindWindow returns the number of windows it found that match your description. It also returns then window handles in an array that you pass to it. Once you have a window handle, you can call many Windows API functions to manipulate it. For example, you could set the focus to it, or move it. The example in this article shows how to set the focus.

Parameters Passed to FindWindowLike Function

The FindWindowLike function searches for windows based on the four parameters you pass it:

FindWindowLike Examples and Their Results

Here are several example calls to FindWindowLike and the results it should return:
  1. r = FindWindowLike(hWnds(), 0, "*", "*", Null)

    Returns: All the available windows.


  2. r = FindWindowLike(hWnds(), 0, "*Excel*", "*", Null)

    Returns: All the windows with "Excel" in the window text.


  3. r = FindWindowLike(hWnds(), 0, "Microsoft Excel*", "XLMAIN", Null)

    Returns: All the windows having window text that begins with "Microsoft Excel" and that contains class name "XLMAIN"


  4. r = FindWindowLike(hWnds(), Form1.Hwnd, "*", "*", "&HA1")

    Returns: The child window of the Form1 window that has an ID of hexadecimal A1.


  5. r = FindWindowLike(hWnds(), Form1.Hwnd, "*", "*", 2)

    Returns: The child window of the Form1 window that has an ID of 2.


Uses for FindWindowLike

The FindWindowLike function can be especially powerful when used in a series of searches. For example, you can search once to find an open instance of the PIF Editor that comes with Microsoft Windows. Then once you have the handle to the PIF Editor window, you can search again for a specific control's window handle by using the PIF Editor's window handle and the ID of the control's window. Here is an example:

   r = FindWindowLike(hWnds(), 0, "PIF Editor*", "Pif", Null)
   ' Assuming the previous returned at least one handle
   r = FindWindowLike(hWnds(), hWnds(1), "*", "*", 103) 

After you have the control's window handle, you can give it the focus and send it keystrokes. In addition, there are a lot of other things you can do once you have a window's handle.

The Sample Code

The sample code listed in the example below uses several Windows API functions to accomplish what was described above. Here are the key ones including descriptions of their uses:

Step-by-Step Example

  1. Start a new Visual Basic project. Form1 is created by default.


  2. Add three Text boxes (Text1, Text2, and Text3) to Form1.


  3. Put the following code in the Form1 click event:
    
       Sub Form_Click ()
          ' Used to return window handles.
          Static hWnds() As Integer
          ' Find window with title "Form1":
          r = FindWindowLike(hWnds(), 0, "Form1", "*", Null)
          If r = 1 Then
             Print "Found "; Hex(hWnds(1))
             ' Find a child window of "Form1" with ID=2:
             ' Notice that the handle from the first search is used.
             r = FindWindowLike(hWnds(), hWnds(1), "*", "*", "&H2")
             If r = 1 Then
                Print "Found child "; Hex(hWnds(1))
                Print "Setting focus to child ..."
                ' Set the focus to the child window with ID=2:
                r = SetFocusAPI(hWnds(1))
             ElseIf r > 1 Then
                ' This should not happen.
                Print "Found more than one child ID=2"
             Else
                Print "Did not find child ID=2"
             End If
          ElseIf r > 1 Then
             Print "Found "; r; " Windows"
          End If
       End Sub
     


  4. Add a new module to the project.


  5. Put the following code in the new module:
    
       Option Explicit
    
       ' The following Declares and constants were taken from WIN30API.TXT
       ' that ships with the Visual Basic Professional Edition.
       ' Enter each of the following Declare statements on one, single line:
    
       Declare Function SetFocusAPI Lib "User" Alias "SetFocus"
          (ByVal hwnd As Integer) As Integer
       Declare Function GetDeskTopWindow Lib "User" () As Integer
       Declare Function GetWindow Lib "User" (ByVal hwnd As Integer,
          ByVal wCmd As Integer) As Integer
       Declare Function GetWindowText Lib "User" (ByVal hwnd As Integer,
          ByVal lpString As String, ByVal aint As Integer) As Integer
       Declare Function GetClassName Lib "User" (ByVal hwnd As Integer,
          ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer
       Declare Function GetParent Lib "User" (ByVal hwnd As Integer) As Integer
       Declare Function GetWindowWord Lib "User" (ByVal hwnd As Integer,
          ByVal nIndex As Integer) As Integer
    
       Global Const GW_HWNDNEXT = 2
       Global Const GW_CHILD = 5
       Global Const GWW_ID = (-12)
    
       '-----------------------------------------------------------------------
    
       'FindWindowLike
       ' - Finds the window handles of the windows matching the specified
       '   parameters
       '
       'hwndArray()
       ' - An integer array used to return the window handles
       '
       'hWndStart
       ' - The handle of the window to search under.
       ' - The routine searches through all of this window's children and their
       '   children recursively.
       ' - If hWndStart = 0 then the routine searches through all windows.
       '
       'WindowText
       ' - The pattern used with the Like operator to compare window's text.
       '
       'ClassName
       ' - The pattern used with the Like operator to compare window's class
       '   name.
       '
       'ID
       ' - A child ID number used to identify a window.
       ' - Can be a decimal number or a hex string.
       ' - Prefix hex strings with "&H" or an error will occur.
       ' - To ignore the ID pass the Visual Basic Null function.
       '
       'Returns
       ' - The number of windows that matched the parameters.
       ' - Also returns the window handles in hWndArray()
       '
       '----------------------------------------------------------------------
       ' Enter the following two lines as one, single line:
       Function FindWindowLike (hWndArray() As Integer, ByVal hWndStart As
          Integer, WindowText As String, Classname As String, ID) As Integer
       Dim hwnd As Integer
       Dim sWindowText As String
       Dim sClassname As String
       Dim sID
       Dim r As Integer
       ' Hold the level of recursion:
       Static level As Integer
       ' Hold the number of matching windows:
       Static iFound As Integer
    
       ' Initialize if necessary:
       If level = 0 Then
          iFound = 0
          ReDim hWndArray(0 To 0)
          If hWndStart = 0 Then hWndStart = GetDeskTopWindow()
       End If
    
       ' Increase recursion counter:
       level = level + 1
    
       ' Get first child window:
       hwnd = GetWindow(hWndStart, GW_CHILD)
    
       Do Until hwnd = 0
          DoEvents ' Not necessary
          ' Search children by recursion:
          r = FindWindowLike(hWndArray(), hwnd, WindowText, Classname, ID)
    
          ' Get the window text and class name:
          sWindowText = Space(255)
          r = GetWindowText(hwnd, sWindowText, 255)
          sWindowText = Left(sWindowText, r)
          sClassname = Space(255)
          r = GetClassName(hwnd, sClassname, 255)
          sClassname = Left(sClassname, r)
    
          ' If window is a child get the ID:
          If GetParent(hwnd) <> 0 Then
             r = GetWindowWord(hwnd, GWW_ID)
             sID = CLng("&H" & Hex(r))
          Else
             sID = Null
          End If
    
          ' Check that window matches the search parameters:
          If sWindowText Like WindowText And sClassname Like Classname Then
             If IsNull(ID) Then
                ' If find a match, increment counter and add handle to array:
                iFound = iFound + 1
                ReDim Preserve hWndArray(0 To iFound)
                hWndArray(iFound) = hwnd
             ElseIf Not IsNull(sID) Then
                If sID = CLng(ID) Then
                   ' If find a match increment counter and add handle to array:
                   iFound = iFound + 1
                   ReDim Preserve hWndArray(0 To iFound)
                   hWndArray(iFound) = hwnd
                End If
             End If
          End If
    
          ' Get next child window:
          hwnd = GetWindow(hwnd, GW_HWNDNEXT)
       Loop
    
       ' Decrement recursion counter:
       level = level - 1
    
       ' Return the number of windows found:
       FindWindowLike = iFound
       End Function
     


  6. Save the Project.


  7. Run the code, and click the form.


First, the program searches for Form1. If Form1 is found, the program searches Form1 for a control with an ID of 2. It should find one because Visual Basic numbers the IDs as you add controls. With three text boxes on Form1, one should have an ID of 2. After finding the control, the code sets the focus to the window by calling SetFocusAPI.

If you set the focus to one of your controls before clicking the Form, you should see the focus shift, always to the same control, when you click the form.


REFERENCES

Microsoft Knowledge Base articles Q72918, Q78001, and Q112649

The Windows SDK Help file that shipped with the Professional Editions of Microsoft Visual Basic versions 2.O and 3.0 for Windows.

"Microsoft Windows Software Development Kit: Programmer's Reference"

"Programming Windows 3.1: The Microsoft Guide to Writing Applications for Windows 3.1," Charles Petzold, Microsoft Press, 1992

"Visual Basic Programmer's Guide to the Windows API," Daniel Appleman, Ziff-Davis Press, 1993

Additional query words: 1.00 2.00 3.00


Keywords          : kbcode kbWndw 
Version           : 1.00 2.00 3.00
Platform          : WINDOWS 
Issue type        : 

Last Reviewed: June 2, 1999