|
|
![]() |
|
||
|
|
|||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||
| Visual Basic System Services FindWindow: Window Title and Class Name Demo |
||
| Posted: | Saturday March 1, 1997 | |
| Updated: | Monday December 26, 2011 | |
| Applies to: | VB4-32, VB5, VB6 | |
| Developed with: | VB6, Windows NT4 | |
| OS restrictions: | None | |
| Author: | VBnet - Randy Birch | |
| Prerequisites |
| None. |
|
|
|
Although setup of the following project appears complicated, all setup code is performed in the form load event. Thus it's just a matter of adding the controls as specified below and running the demo. This demo implements the FindWindowLike routine. The FindWindowLike method does not require you to first know the precise (current) window name of the application you're trying to locate, allowing even partial strings in searching out the window. The only condition that the code makes is that, at a minimum, the ClassName parameter be at least "*". The original author of the FindWindowLike routine is unknown. |
| BAS Module Code |
| None. |
|
|
| Form Code |
|
|
Start a new project, and add the following controls to the form:
Add the following code: |
|
|
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. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Dim hwndSelected As Long
Dim sClassSelected As String
Dim sTitleSelected As String
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type WINDOWPLACEMENT
Length As Long
flags As Long
showCmd As Long
ptMinPosition As POINTAPI
ptMaxPosition As POINTAPI
rcNormalPosition As RECT
End Type
Private Const LB_SETTABSTOPS = &H192
Private Const GW_HWNDNEXT = 2
Private Const GW_CHILD = 5
Private Const GWW_ID = (-12)
Private Const SW_SHOWNORMAL = 1
Private Const SW_SHOWMINIMIZED = 2
Private Const SW_SHOWMAXIMIZED = 3
Private Const SW_SHOWNOACTIVATE = 4
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Private Declare Function GetWindowPlacement Lib "user32" _
(ByVal hwnd As Long, _
lpwndpl As WINDOWPLACEMENT) As Long
Private Declare Function GetWindowRect Lib "user32" _
(ByVal hwnd As Long, _
lpRect As RECT) 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 MoveWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal bRepaint As Long) As Long
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function SetForegroundWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function SetWindowPlacement Lib "user32" _
(ByVal hwnd As Long, _
lpwndpl As WINDOWPLACEMENT) As Long
Private Declare Function ShowWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal nCommand5 As Long) As Long
Private Sub Form_Load()
'The control positioning in this routine
'was calculated on a screen using small fonts.
'If you use large fonts you'll have to tweak the
'settings slightly.
Load Command4(1)
Load Command4(2)
Command4(0).Visible = True
Command4(1).Visible = True
Command4(2).Visible = True
Load Label2(1)
Load Label2(2)
Load Label2(3)
Load Label2(4)
Label2(0).Visible = True
Label2(1).Visible = True
Label2(2).Visible = True
Label2(3).Visible = True
Label2(4).Visible = True
Label2(0).AutoSize = True
Label2(1).AutoSize = True
Label2(2).AutoSize = True
Label2(3).AutoSize = True
Label2(4).AutoSize = True
With Me
.Width = 8225
.Height = 5065
.Move (Screen.Width - .Width) \ 2, (Screen.Height - .Height) \ 2
.Caption = "VBnet FindWindow / Window Title and Class Name Demo"
End With
Command1.Caption = "Reset Names"
Command2.Caption = "Find"
Command3.Caption = "Show"
Command4(0).Caption = "< Tab"
Command4(1).Caption = "Tab >"
Command4(2).Caption = "Reset"
Command5.Caption = "Use as Window Class"
Command6.Caption = "Use as Window Title"
Command7.Caption = "End"
Label1.Caption = "<results here>"
Lable1.AutoSize = True
Label2(0).Caption = "Class name (* for any)"
Label2(1).Caption = "Full or partial title (* for any)"
Label2(2).Caption = "hwnd:"
Label2(3).Caption = "Class name:"
Label2(4).Caption = "Full window title:"
Text1.Move 200, 400, 1700, 285
Text2.Move 2000, 400, 3000, 285
Label2(0).Move Text1.Left, Text1.Top - 200
Label2(1).Move Text2.Left, 150
Command1.Move 5300, Text1.Top - 50, 1500, 365
Label1.Move 200, 800
List1.Move 200, 1400, Me.ScaleWidth - 400, 2200
Label2(2).Move List1.Left, List1.Top - 250
Label2(3).Move List1.Left + 940, List1.Top - 250
Label2(4).Move List1.Left + 2500, List1.Top - 250
Command2.Move 200, 3700, 2200, 365
Command3.Move 200, 4100, 2200, 365
Command4(0).Move 2500, Command2.Top, 800, 365
Command4(1).Move 3300, Command2.Top, 800, 365
Command4(2).Move 4100, Command2.Top, 800, 365
Command5.Move 5000, Command2.Top, 1800, 365
Command6.Move 5000, Command3.Top, 1800, 365
Command7.Move 7000, Command5.Top, 800, 365
'Initialize controls
Text2.Text = "*Microsoft Internet Explorer"
Text1.Text = "*"
Command4_Click 2
End Sub
Private Sub Command1_Click()
'Initialize controls
Text2.Text = "*Microsoft Internet Explorer"
Text1.Text = "*"
End Sub
Private Sub Command2_Click()
'FIND
Dim hWnds() As Long 'Used to return window handles
Dim cnt As Long
Dim sTitle As String
Dim sClass As String
'Initialize controls
Command6.Enabled = False
Command5.Enabled = False
Command3.Enabled = False
List1.Clear
'Set the FindWindowLike text values
sTitle = Text2.Text & "*"
sClass = Text1.Text
cnt = FindWindowLike(hWnds(), 0, sTitle, sClass)
Label1.Caption = "Found : " & cnt & " windows."
Command4(0).Enabled = cnt > 0
Command4(1).Enabled = cnt > 0
End Sub
Private Sub Command3_Click()
'SHOW
Dim msg As String
Dim currRect As RECT
Dim currWinP As WINDOWPLACEMENT
currWinP.Length = Len(currWinP)
Call GetWindowPlacement(hwndSelected, currWinP)
If currWinP.showCmd = SW_SHOWMINIMIZED Then
msg = "The selected window is presently minimized." & vbCrLf & vbCrLf
msg = msg & "Select: " & vbCrLf
msg = msg & " Yes to restore it to the top," & vbCrLf
msg = msg & " No to restore it without activating, or" & vbCrLf
msg = msg & " Cancel to abort this action."
Select Case MsgBox(msg, 291, sTitleSelected)
Case vbYes
currWinP.Length = Len(currWinP)
currWinP.flags = 0&
currWinP.showCmd = SW_SHOWNORMAL
Call SetWindowPlacement(hwndSelected, currWinP)
Case vbNo
currWinP.Length = Len(currWinP)
currWinP.flags = 0&
currWinP.showCmd = SW_SHOWNOACTIVATE
Call SetWindowPlacement(hwndSelected, currWinP)
Case Else
End Select
Else
Select Case MsgBox("Bring the selected window to the top?", 292, sTitleSelected)
Case vbYes
Call SetForegroundWindow(hwndSelected)
Case Else
End Select
End If
If Err Then MsgBox "Couldn't activate " & sTitleSelected, , Me.Caption
End Sub
Private Sub Command4_Click(Index As Integer)
'TAB ADJUST - moves tabstops to align wide items
Static classTab As Long
Static winTab As Long
Select Case Index
Case 0: classTab = classTab& - 2: winTab = winTab - 3
Case 1: classTab = classTab& + 2: winTab = winTab + 3
Case 2: classTab = 42: winTab = 110
End Select
If classTab < 26 Then classTab = 26
If winTab < 90 Then winTab = 90
Command4(0).Enabled = (classTab <> 35 And winTab <> 90)
ReDim tabs(1 To 2) As Long
tabs(1) = classTab 'class
tabs(2) = winTab 'window title
'reset the initial tabstops then set the defined ones
Call SendMessage(List1.hwnd, LB_SETTABSTOPS, 0&, ByVal 0&)
Call SendMessage(List1.hwnd, LB_SETTABSTOPS, UBound(tabs), tabs(1))
List1.Refresh
Command4(2).Enabled = (classTab <> 42) And (winTab <> 110)
End Sub
Private Sub Command5_Click()
'SET CLASS TEXT - if item selected in list
If Len(sClassSelected) > 0 Then
Text1.Text = sClassSelected
End If
End Sub
Private Sub Command7_Click()
Unload Me
End Sub
Private Sub Command6_Click()
'SET TITLE TEXT - if item selected in list
If Len(sTitleSelected) > 0 Then
Text2.Text = sTitleSelected
End If
End Sub
Private Sub List1_Click()
Dim sItem As String
Dim pos1 As Integer
Dim pos2 As Integer
Command3.Enabled = List1.ListIndex > -1 'Show button
Command5.Enabled = List1.ListIndex > -1 'Use as Class button
Command6.Enabled = List1.ListIndex > -1 'Use as Title button
'extract the data from the selected list item
'get the selected item's handle
sItem = List1.List(List1.ListIndex)
pos1 = InStr(sItem, vbTab)
'get the selected item class name
If pos1 Then hwndSelected = CLng(Left$(sItem, pos1 - 1))
'get the selected item window class and title
sItem = Mid$(sItem, pos1 + 1, Len(sItem))
pos2 = InStr(sItem, vbTab)
If pos2 Then
sClassSelected = Left$(sItem, pos2 - 1)
sTitleSelected = Mid$(sItem, pos2 + 1, Len(sItem))
End If
End Sub
Private Function FindWindowLike(hWndArray() As Long, _
ByVal hWndStart As Long, _
WindowText As String, _
Classname As String) As Long
Dim hwnd As Long
Dim sWindowText As String
Dim sClassname As String
Dim r As Long
'Hold the level of recursion and
'hold the number of matching windows
Static level As Long
Static found As Long
'Initialize if necessary
If level = 0 Then
found = 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
'Search children by recursion
Call FindWindowLike(hWndArray(), hwnd, WindowText, Classname)
'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)
'Check that window matches the search parameters
If (sWindowText Like WindowText) And (sClassname Like Classname) Then
found = found + 1
ReDim Preserve hWndArray(0 To found)
hWndArray(found) = hwnd
List1.AddItem hWndArray(found) & vbTab & sClassname & vbTab & sWindowText
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 = found
End Function
|
| Comments |
| Save the project, then run. Enter the full or partial
window title to locate, and/or the class name, if known. Note that the search is case-sensitive.
Pressing Find, the list box will return the matches. Select an item, and either:
Press Find again to narrow the search, repeating as needed. At any point, once an item is selected, the Show Selected button will become enabled. When pressed, depending on the current window state of the selected item, one of two Message boxes will appear. Use the buttons to change the column spacing of the list, if needed. Note as well that the textbox containing the text you've entered will also appear in the list because of the call to the GetWindowText API. You could code the routine to only list parent windows by discarding those who return a value to an IsChild() API call. |
|
|
|
|
|
|||||
|
|||||
|
|
|||||
|
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |
![]() |