|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Enumeration/Callback Routines EnumWindows: Enumerate (and Restore) a Window via Callback |
|
Posted: | Wednesday March 1, 2000 |
Updated: | Monday December 26, 2011 |
Applies to: | VB5, VB6 |
Developed with: | VB5, Windows 95 |
OS restrictions: | None |
Author: | VBnet - Randy Birch |
Related: |
SetWindowPlacement: Restore and Activate a Window via its hWnd GetWindowThreadProcessId: Obtain the hWnd of an App Started with Shell() |
Prerequisites |
None. |
|
Here's
a quick routine that will enumerate all top-level windows and provide a Restore feature to restore the app to the foreground. Once again the
venerable EnumWindows API forms the base for this demo, with supporting roles going to GetWindowPlacement, BringWindowToTop, and friends.
The routine enumerates the top-level windows and adds each to a list, also assigning the window's handle to the list item's ItemData property. On selecting an item, GetWindowPlacement is called and the current window state is reflected in one of the three option buttons. Pressing the Restore button activates the selected window, and restores it regardless of its previous state. As coded, the option buttons are for displaying the current state, but a simple change in the RestoreWindow routine would provide the ability to specify the restore state. Where a window is top-level, but has no title, the class name is shown along with the word (class) following it (as with item 1 in the list). |
BAS Module Code |
Place the following code into the general declarations area of a bas module: |
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Public Type POINTAPI x As Long y As Long End Type Public Type WINDOWPLACEMENT Length As Long flags As Long showCmd As Long ptMinPosition As POINTAPI ptMaxPosition As POINTAPI rcNormalPosition As RECT End Type Public Const SW_SHOWNORMAL = 1 Public Const SW_SHOWMINIMIZED = 2 Public Const SW_SHOWMAXIMIZED = 3 Public Const SW_SHOWNOACTIVATE = 4 Public Const WPF_RESTORETOMAXIMIZED = &H2 Public Declare Function EnumWindows Lib "user32" _ (ByVal lpEnumFunc As Long, _ ByVal lParam As Long) As Long Private Declare Function GetWindowText Lib "user32" _ Alias "GetWindowTextA" _ (ByVal hwnd As Long, _ ByVal lpString As String, _ ByVal cch As Long) As Long Private Declare Function GetClassName Lib "user32" _ Alias "GetClassNameA" _ (ByVal hwnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Declare Function GetWindowTextLength Lib "user32" _ Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long Private Declare Function IsWindowVisible Lib "user32" _ (ByVal hwnd As Long) As Long Private Declare Function GetParent Lib "user32" _ (ByVal hwnd As Long) As Long Private Declare Function IsWindowEnabled Lib "user32" _ (ByVal hwnd As Long) As Long Public Declare Function IsZoomed Lib "user32" _ (ByVal hwnd As Long) As Long Public Declare Function GetWindowPlacement Lib "user32" _ (ByVal hwnd As Long, _ lpwndpl As WINDOWPLACEMENT) As Long Public Declare Function SetWindowPlacement Lib "user32" _ (ByVal hwnd As Long, _ lpwndpl As WINDOWPLACEMENT) As Long Public Declare Function BringWindowToTop Lib "user32" _ (ByVal hwnd As Long) As Long Public Declare Function SetForegroundWindow Lib "user32" _ (ByVal hwnd As Long) As Long Public Function EnumWindowProc(ByVal hwnd As Long, ByVal lParam As Long) As Long 'working vars Dim nSize As Long Dim sTitle As String Dim pos As Integer 'eliminate windows that are not top-level. If GetParent(hwnd) = 0& And _ IsWindowVisible(hwnd) And _ IsWindowEnabled(hwnd) Then 'get the size of the string required 'to hold the window title nSize = GetWindowTextLength(hwnd) 'if the return is 0, there is no title If nSize > 0 Then sTitle = Space$(nSize + 1) Call GetWindowText(hwnd, sTitle, nSize + 1) sTitle = TrimNull(sTitle) Else 'no title, so get the class name instead sTitle = Space$(64) Call GetClassName(hwnd, sTitle, 64) sTitle = TrimNull(sTitle) & " (class)" End If 'add the items to the list Form1.List1.AddItem sTitle Form1.List1.ItemData(Form1.List1.NewIndex) = hwnd End If 'To continue enumeration, return True 'To stop enumeration return False (0). 'When 1 is returned, enumeration continues 'until there are no more windows left. EnumWindowProc = 1 End Function Public Function TrimNull(startstr As String) As String Dim pos As Integer pos = InStr(startstr, Chr$(0)) If pos Then TrimNull = Left$(startstr, pos - 1) Exit Function End If TrimNull = startstr End Function |
Form Code |
To a form, add a list (List1), a command button (Command1), a label (Label1) and a control array of option buttons using indexes 1 through 3 (Option1(1)-Option1(3). Option1(0) is not used and can be deleted. Add the following code to the form: |
|
Option Explicit Private Sub RestoreWindow(hWndToRestore As Long) Dim currWinP As WINDOWPLACEMENT 'if a window handle passed If hWndToRestore Then 'prepare the WINDOWPLACEMENT type 'to receive the window coordinates 'of the specified handle currWinP.Length = Len(currWinP) 'get the info... If GetWindowPlacement(hWndToRestore, currWinP) > 0 Then 'based on the returned info, 'determine the window state If currWinP.showCmd = SW_SHOWMINIMIZED Then 'it is minimized, so restore it With currWinP .Length = Len(currWinP) .flags = 0& .showCmd = SW_SHOWNORMAL End With Call SetWindowPlacement(hWndToRestore, currWinP) Else 'it is on-screen, so make it visible Call SetForegroundWindow(hWndToRestore) Call BringWindowToTop(hWndToRestore) End If End If End If End Sub Private Sub List1_Click() Dim hWndSelected As Long Dim currWinP As WINDOWPLACEMENT hWndSelected = List1.ItemData(List1.ListIndex) Label2.Caption = "hwnd: " & hWndSelected 'if a window handle... If hWndSelected Then 'prepare the WINDOWPLACEMENT type 'to receive the window coordinates 'of the specified handle currWinP.Length = Len(currWinP) 'get the info... If GetWindowPlacement(hWndSelected, currWinP) > 0 Then 'based on the returned info, 'determine the window state. 'Conveniently, the option array 'indices and the SW_ window state 'values match, allowing the direct 'assigning of the values. Option1(currWinP.showCmd).Value = True End If End If End Sub Private Sub Command1_Click() 'retrieve the hwnd from the list's 'ItemData and pass to the RestoreWindow routine RestoreWindow List1.ItemData(List1.ListIndex) End Sub Private Sub Form_Load() Call EnumWindows(AddressOf EnumWindowProc, &H0) If List1.ListCount Then List1.ListIndex = 0 Label1.Caption = List1.ListCount & " windows found." End Sub |
Comments |
You could add or remove API or logic in the Enum proc to modify the results. And if you want to add more info into the list itself, you might want to take a look at designing the listbox layout using the CoolTabs util. |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |