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. |
|