 |

02-19-2004, 12:17 PM
|
 |
Ultimate Contributor
|
|
Join Date: Aug 2002
Location: Richardson, Texas
Posts: 1,617
|
|
Finding the handle of a combo-box list.
|
^^^Anyone know how to do this? I can get the handle of the combo-box itself, but I need the handle of the drop-down list to obtain x/y coordinates. Since the form is sizable/movable (and the child handles change everytime the application is launched so Spy++ is out of the question) I have to find this info every time the button is clicked. Just for kicks, here's snippets of my code.
***WARNING: it does a lot of switching from form to module to different module and back to form so if it's confusing, I'm sorry.***
Code:
'This is on the form
Option Explicit
Private Sub cmdGo_Click()
Dim hParent As Long
Dim FilterHandle As Long
Dim FilterListHandle As Long
Dim ReportHandle As Long
Dim FilterName As String
Dim ReportName As String
Dim FormatType As String
Dim Results As String
Dim Results1 As String
Dim FilterIndex As Long
Dim ReportIndex As Long
Dim FilterIndexCount As Long
Dim WaitString As String
Dim x As Integer
Me.AutoRedraw = True
hParent = FindWindow(vbNullString, "Open Claims")
ShowWindow hParent, SW_SHOWNORMAL
SetForegroundWindow (hParent)
FilterHandle = Find_Filter
FilterListHandle = Find_FilterList
ReportHandle = Find_Report
x = 0
Do Until x = (GetComboCount(FilterHandle) - 1)
FilterIndex = SetComboIndex(x, FilterHandle)
FilterName = GetText(FilterHandle)
If FilterName = "Texas Inventory Over 5 Days" Then
Results = FilterName
Exit Do
Else
x = x + 1
End If
Loop
If ComboDropped(FilterHandle) = False Then OpenComboList (FilterHandle)
CenterLeftClickDownFilter (FilterListHandle)
CenterLeftClickUpFilter (FilterListHandle)
Sleep 5000
CenterLeftClickDown (ReportHandle)
CenterLeftClickUp (ReportHandle)
Do Until ReportName = "Report In Excel"
ReportName = GetText(ReportHandle)
If ReportName <> "Report In Excel" Then SendKeys "{down}"
Loop
End Sub
Here are all the functions being referenced in the above code:
Code:
Function Find_Filter()
Dim Win_Buff1 As Long
Dim Win_Buff0 As Long
Dim sddx As Integer
Win_Buff1 = FindWindow("ThunderRT6FormDC", "Open Claims")
If Win_Buff1 = 0 Then Win_Buff1 = FindWindow("ThunderRT6FormDC", vbNullString)
Win_Buff0 = findchildbyclass(Win_Buff1, "ThunderRT6ComboBox")
If Win_Buff0 = 0 Then Win_Buff0 = findchildbytitle(Win_Buff1, "All Open Inventory")
Win_Buff0 = GetWindow(Win_Buff1, GW_CHILD)
For sddx = 1 To 17
Win_Buff0 = GetWindow(Win_Buff0, GW_HWNDNEXT)
Next sddx
Find_Filter = Win_Buff0
End Function
'-------------------------------------------------
Function Find_Report()
Dim Win_Buff3 As Long
Dim Win_Buff2 As Long
Dim Win_Buff1 As Long
Dim Win_Buff0 As Long
Dim sddx As Integer
Win_Buff3 = FindWindow("ThunderRT6FormDC", "Open Claims")
If Win_Buff3 = 0 Then Win_Buff3 = FindWindow("ThunderRT6FormDC", vbNullString)
Win_Buff2 = findchildbyclass(Win_Buff3, "AfxWnd40")
If Win_Buff2 = 0 Then Win_Buff2 = findchildbytitle(Win_Buff3, "")
Win_Buff2 = GetWindow(Win_Buff3, GW_CHILD)
For sddx = 1 To 16
Win_Buff2 = GetWindow(Win_Buff2, GW_HWNDNEXT)
Next sddx
Win_Buff1 = findchildbyclass(Win_Buff2, "ThunderRT6ComboBox")
If Win_Buff1 = 0 Then Win_Buff1 = findchildbytitle(Win_Buff2, "Report In Excel")
Win_Buff1 = GetWindow(Win_Buff2, GW_CHILD)
Win_Buff0 = findchildbyclass(Win_Buff1, "Edit")
If Win_Buff0 = 0 Then Win_Buff0 = findchildbytitle(Win_Buff1, "Format A - Report")
If Win_Buff0 = 0 Then Win_Buff0 = findchildbytitle(Win_Buff1, "Format B - Report")
If Win_Buff0 = 0 Then Win_Buff0 = findchildbytitle(Win_Buff1, "Format C - Report")
If Win_Buff0 = 0 Then Win_Buff0 = findchildbytitle(Win_Buff1, "Format D - Report")
If Win_Buff0 = 0 Then Win_Buff0 = findchildbytitle(Win_Buff1, "Report In Excel")
Win_Buff0 = GetWindow(Win_Buff1, GW_CHILD)
Find_Report = Win_Buff0
End Function
'-----------------------------------------------------
Function Find_FilterList()
Dim Win_Buff1 As Long
Dim Win_Buff0 As Long
Dim sddx As Integer
Win_Buff1 = FindWindow("#32769", "")
If Win_Buff1 = 0 Then Win_Buff1 = FindWindow("#32769", vbNullString)
Win_Buff0 = findchildbyclass(Win_Buff1, "ComboLBox")
If Win_Buff0 = 0 Then Win_Buff0 = findchildbytitle(Win_Buff1, "")
Win_Buff0 = GetWindow(Win_Buff1, GW_CHILD)
For sddx = 1 To 2
Win_Buff0 = GetWindow(Win_Buff0, GW_HWNDNEXT)
Next sddx
Find_FilterList = Win_Buff0
End Function
I'll post the rest of the functions on the next post so that I don't accidentaly for over the post limit....
|
|

02-19-2004, 12:19 PM
|
 |
Ultimate Contributor
|
|
Join Date: Aug 2002
Location: Richardson, Texas
Posts: 1,617
|
|
Here's the rest of the functions. Ah, heck. I'll just post the whole module in two chunks. First part here, rest on the next post.
This module was created to do anything regarding sending/receiving info from other applications. (Which is why the bas is called TextSender).
Code:
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd 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 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 GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function SetActiveWindow Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As Any, ByVal lpszWindow As Any) As Long
Private Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As INPUT_TYPE, ByVal cbSize As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function EnableWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal fEnable As Long) As Long
Public Type MOUSEINPUT
dx As Long
dy As Long
mouseData As Long
dwFlags As Long
time As Long
dwExtraInfo As Long
End Type
Public Const MOUSEEVENTF_RIGHTDOWN = &H8
Public Const MOUSEEVENTF_RIGHTUP = &H10
Public Type KEYBDINPUT
wVk As Integer
wScan As Integer
dwFlags As Long
time As Long
dwExtraInfo As Long
End Type
Public Const VK_P = &H50 ' using vbKeyP instead would also work
Public Const KEYEVENTF_KEYUP = &H2
Public Type INPUT_TYPE
dwType As Long
xi(0 To 23) As Byte
End Type
Public Const INPUT_KEYBOARD = 1
Public Const INPUT_MOUSE = 0
Public Const KEYEVENTF_EXTENDEDKEY = &H1
Public Const WM_STARTMESSAGE = &H43A33AAA
Public Const WM_ENDMESSAGE = &H43A33AAB
Public Const WM_SENDMESSAGE = &H43A33AAC
'*** Get/Set Stuff Const ***
Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101
Public Const WM_CHAR = &H102
Public Const WM_GETTEXT = &HD
Public Const WM_GETTEXTLENGTH = &HE
Public Const WM_SETTEXT = &HC
Public Const EM_GETPASSWORDCHAR = &HD2
Public Const EM_SETPASSWORDCHAR = &HCC
Public Const CB_SETFOCUS = &H468
Public Const BN_DISABLE = 4
'*** MouseButton Const
Const WM_LBUTTONUP = &H202
Const WM_LBUTTONDOWN = &H201
Const MK_CONTROL = &H8
Const MK_LBUTTON = &H1
Const MK_MBUTTON = &H10
Const MK_RBUTTON = &H2
Const MK_SHIFT = &H4
Const MK_XBUTTON1 = &H20
Const MK_XBUTTON2 = &H40
'*** CHECK BOX CONST***
Public Const BM_SETCHECK = &HF1
Public Const BST_CHECKED = &O1
Public Const BST_INDETERMINATE = &O2
Public Const BST_UNCHECKED = &O0
'*** Button Stuff ***
Public Const BM_CLICK = &HF5
'*** Combo Box Stuff ***
Const CB_ADDSTRING = &H143
Const CB_ERR = -1
Const CB_ERRSPACE = -2
Const CB_RESETCONTENT = &H14B
Const CB_DELETESTRING = &H144
Const CB_GETCOUNT = &H146
Const CB_GETLBTEXT = &H148
Const CB_GETLBTEXTLEN = &H149
Const CB_GETCURSEL = &H147
Const CB_GETDROPPEDSTATE = &H157
Const CB_INSERTSTRING = &H14A
Const CB_SETCURSEL = &H14E
Const CB_SHOWDROPDOWN = &H14F
|
|

02-19-2004, 12:21 PM
|
 |
Ultimate Contributor
|
|
Join Date: Aug 2002
Location: Richardson, Texas
Posts: 1,617
|
|
And lastly, the function parts of the last post:
Code:
Function ClickMessageButton(MessageDialog As String, ButtonDialog As String) As Boolean
Dim hwndDialog As Long ' handle to the dialog box
Dim hwndButton As Long ' handle to the Resume button
Dim retval As Long ' return value
' First, see if the dialog box (titled "Inactivity Warning" is currently open.
hwndDialog = FindWindow(CLng(0), MessageDialog)
If hwndDialog = 0 Then
ClickMessageButton = False
Exit Function
Else
ClickMessageButton = True
End If
' Now get a handle to the "Resume" button in the dialog.
hwndButton = FindWindowEx(hwndDialog, 0, CLng(0), ButtonDialog)
' After making sure that the dialog box is the active window, click "Resume".
retval = SetActiveWindow(hwndDialog)
retval = SendMessage(hwndButton, BM_CLICK, ByVal CLng(0), ByVal CLng(0))
retval = SendMessage(hwndButton, BM_CLICK, ByVal CLng(0), ByVal CLng(0))
End Function
Function CenterLeftClickUp(hwnd)
Dim xcoord As Long, ycoord As Long ' x and y coordinates of the faked cursor position
Dim packed As Long ' the coordinates "packed" into a single 32-bit integer
Dim winrect As RECT ' receives coordinates of the window
Dim retval As Long ' return value
' First, get the coordinates of window Form1.
retval = GetWindowRect(hwnd, winrect)
' Use the coordinates to calculate the midpoint of Form1.
xcoord = (winrect.Right - winrect.Left) / 2
ycoord = (winrect.Bottom - winrect.Top) / 2
' Now pack the coordinates into the appropriate words of the value
packed = (ycoord * &H10000) + xcoord
' Make Form1 think the left mouse button was just pressed in that position.
Call SendMessage(hwnd, WM_LBUTTONUP, ByVal CLng(0), ByVal packed)
End Function
Function CenterLeftClickDown(hwnd)
Dim xcoord As Long, ycoord As Long ' x and y coordinates of the faked cursor position
Dim packed As Long ' the coordinates "packed" into a single 32-bit integer
Dim winrect As RECT ' receives coordinates of the window
Dim retval As Long ' return value
' First, get the coordinates of window Form1.
retval = GetWindowRect(hwnd, winrect)
' Use the coordinates to calculate the midpoint of Form1.
xcoord = (winrect.Right - winrect.Left) / 2
ycoord = (winrect.Bottom - winrect.Top) / 2
' Now pack the coordinates into the appropriate words of the value
packed = (ycoord * &H10000) + xcoord
' Make Form1 think the left mouse button was just pressed in that position.
Call SendMessage(hwnd, WM_LBUTTONDOWN, ByVal CLng(MK_LBUTTON), ByVal packed)
End Function
Function Send_CheckBox(hwnd As Long, Checked As Boolean)
If Checked = True Then
retval = SendMessage(hwnd, BM_SETCHECK, ByVal CLng(BST_CHECKED), ByVal CLng(0))
Else
retval = SendMessage(hwnd, BM_SETCHECK, ByVal CLng(BST_UNCHECKED), ByVal CLng(0))
End If
End Function
Function GetText(Ihwnd As Long) As String
Dim textlen As Long
Dim Text As String
textlen = SendMessage(Ihwnd, WM_GETTEXTLENGTH, 0, 0)
If textlen = 0 Then
GetText = ">No text for this class<"
Exit Function
End If
textlen = textlen + 1
Text = Space$(textlen)
textlen = SendMessage(Ihwnd, WM_GETTEXT, textlen, ByVal Text)
GetText = Left$(Text, textlen)
End Function
Public Sub Send_Text(Message As String, hwnd As Long)
Dim wintext As String
Dim retval As Long
wintext = Message
retval = SendMessage(hwnd, WM_SETTEXT, ByVal CLng(0), ByVal wintext)
If retval = 0 Then
Debug.Print "Unable to set the text of Form1."
Else
Debug.Print "The text of Form1 was successfully set."
End If
End Sub
Function GetPassChar(hwnd As Long)
Dim passchar As Long
passchar = SendMessage(hwnd, EM_GETPASSWORDCHAR, ByVal CLng(0), ByVal CLng(0))
If passchar > 0 Then GetPassChar = Chr(passchar)
End Function
Function SetPassChar(hwnd As Long, TheCharacter As String)
Call SendMessage(hwnd, EM_SETPASSWORDCHAR, ByVal CLng(Asc(TheCharacter)), ByVal CLng(0))
End Function
Function RemovePasswordChar(hwnd As Long)
Call SendMessage(hwnd, EM_SETPASSWORDCHAR, CLng(0), ByVal CLng(0))
End Function
Function ClickButton(hwnd As Long)
Call SendMessage(hwnd, BM_CLICK, ByVal CLng(0), ByVal CLng(0))
End Function
Function SetTheFocus(hwnd As Long)
Call SendMessage(hwnd, CB_SETFOCUS, ByVal CLng(0), ByVal CLng(0))
End Function
Public Sub Timeout(PauseTime)
StartTime = Timer
Do While Timer - StartTime < PauseTime
DoEvents
Loop
End Sub
'***** COMBO BOX STUFF *****
Function AddComboItem(TextToAdd As String, hwnd As Long)
Call SendMessage(hwnd, CB_ADDSTRING, ByVal CLng(0), ByVal TextToAdd)
End Function
Function ClearComboBox(hwnd As Long)
Call SendMessage(hwnd, CB_RESETCONTENT, ByVal CLng(0), ByVal CLng(0))
End Function
Function RemoveComboItem(Index As Integer, hwnd As Long)
Call SendMessage(hwnd, CB_DELETESTRING, Index, ByVal CLng(0))
End Function
Function GetComboItem(Index As Integer, hwnd As Long)
Dim count As Long
Dim s2l As Long
Dim itemtext As String
Dim textlen As Long
count = SendMessage(hwnd, CB_GETCOUNT, ByVal CLng(0), ByVal CLng(0))
If count < 1 Then GetComboItem = "": Exit Function
textlen = SendMessage(hwnd, CB_GETLBTEXTLEN, ByVal Index, ByVal CLng(0))
If textlen < 0 Then GetComboItem = "": Exit Function
itemtext = Space(textlen) & vbNullChar
textlen = SendMessage(hwnd, CB_GETLBTEXT, ByVal Index, ByVal itemtext)
GetComboItem = Left(itemtext, textlen)
End Function
Function GetComboText(hwnd As Long)
Dim Index As Integer
Index = GetComboIndex(hwnd)
If Index = -1 Then GetComboText = "": Exit Function
GetComboText = GetComboItem(Index, hwnd)
End Function
Function GetComboIndex(hwnd As Long)
GetComboIndex = SendMessage(hwnd, CB_GETCURSEL, ByVal CLng(0), ByVal CLng(0))
End Function
Function ComboDropped(hwnd As Long) As Boolean
If SendMessage(hwnd, CB_GETDROPPEDSTATE, ByVal CLng(0), ByVal CLng(0)) = 0 Then ComboDropped = False Else ComboDropped = True
End Function
Function ChangeCombotList(TheText As String, Index As Integer, hwnd As Long)
Call SendMessage(hwnd, CB_INSERTSTRING, ByVal Index, ByVal TheText)
End Function
Function ClearCombo(hwnd As Long)
Call SendMessage(hwnd, CB_RESETCONTENT, ByVal CLng(0), ByVal CLng(0))
End Function
Function SetComboIndex(Index As Integer, hwnd As Long)
Call SendMessage(hwnd, CB_SETCURSEL, ByVal Index, ByVal CLng(0))
End Function
Function OpenComboList(hwnd As Long)
Call SendMessage(hwnd, CB_SHOWDROPDOWN, ByVal CLng(1), ByVal CLng(0))
End Function
Function CloseComboList(hwnd As Long)
Call SendMessage(hwnd, CB_SHOWDROPDOWN, ByVal CLng(0), ByVal CLng(0))
End Function
Function Test(hwnd As Long)
Call SendMessage(hwnd, BN_DISABLE, ByVal CLng(0), ByVal CLng(0))
End Function
Function GetComboCount(hwnd As Long)
GetComboCount = SendMessage(hwnd, CB_GETCOUNT, ByVal CLng(0), ByVal CLng(0))
End Function
Function CenterLeftClickUpFilter(hwnd)
Dim xcoord As Long, ycoord As Long ' x and y coordinates of the faked cursor position
Dim packed As Long ' the coordinates "packed" into a single 32-bit integer
Dim winrect As RECT ' receives coordinates of the window
Dim retval As Long ' return value
' First, get the coordinates of window Form1.
retval = GetWindowRect(hwnd, winrect)
' Use the coordinates to calculate the midpoint of Form1.
xcoord = (winrect.Right - winrect.Left) / 2
ycoord = (140 - winrect.Top) / 2
' Now pack the coordinates into the appropriate words of the value
packed = (ycoord * &H10000) + xcoord
' Make Form1 think the left mouse button was just pressed in that position.
Call SendMessage(hwnd, WM_LBUTTONUP, ByVal CLng(0), ByVal packed)
End Function
Function CenterLeftClickDownFilter(hwnd)
Dim xcoord As Long, ycoord As Long ' x and y coordinates of the faked cursor position
Dim packed As Long ' the coordinates "packed" into a single 32-bit integer
Dim winrect As RECT ' receives coordinates of the window
Dim retval As Long ' return value
' First, get the coordinates of window Form1.
retval = GetWindowRect(hwnd, winrect)
' Use the coordinates to calculate the midpoint of Form1.
xcoord = (winrect.Right - winrect.Left) / 2
ycoord = (140 - winrect.Top) / 2
' Now pack the coordinates into the appropriate words of the value
packed = (ycoord * &H10000) + xcoord
' Make Form1 think the left mouse button was just pressed in that position.
Call SendMessage(hwnd, WM_LBUTTONDOWN, ByVal CLng(MK_LBUTTON), ByVal packed)
End Function
Hopefully something in these three posts will help someone out in the future; and as an even more hopeful event, someone will be generous enough to help me out in grabbing the handle of the actual listing of a combo-box. 
|
|

02-20-2004, 10:49 AM
|
 |
Political Coder
Retired Moderator * Guru *
|
|
Join Date: Mar 2001
Location: London, England
Posts: 8,037
|
|
Last edited by Squirm; 02-20-2004 at 11:04 AM.
|

02-20-2004, 11:20 AM
|
 |
Ultimate Contributor
|
|
Join Date: Aug 2002
Location: Richardson, Texas
Posts: 1,617
|
|
That is more than likely exactly what I was looking for. I ended up taking a different approach, however. I ended up opening the combo list with code and using the SetCursorPos to the item and using the LBUTTONDOWN/UP to select the item. As far as getting the X,Y coordinates of top item in the list, I just did some figuring and used the coords from the parent and figured how far in from the left and how far down from the top the combo-box list was. Something like this:
Code:
xcoord = (winrect.Left + 78) 'This is how far the middle of the combo-
'box is in from the left of the parent.
ycoord = (winrect.Top + 52) 'This is how far the middle of the combo-
'box is in from the top of the parent.
'***NOTE***
'The xcoord/ycoord is the middle of the first item in the list of the
'combo-box, found after I drop/open the box.
That probably didn't make a whole lot of sense in regards to what I was originally asking, but I think this method will work out quite well. So far it has been fine.
But thanks for the help!
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|