Go Back  Xtreme Visual Basic Talk > Legacy Visual Basic (VB 4/5/6) > API > Finding the handle of a combo-box list.


Reply
 
Thread Tools Display Modes
  #1  
Old 02-19-2004, 12:17 PM
meteo's Avatar
meteo meteo is offline
Ultimate Contributor
 
Join Date: Aug 2002
Location: Richardson, Texas
Posts: 1,617
Default 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....
__________________
WARNING: Self-Taught Programmer. Use at your own risk.
Standards and Practices
Reply With Quote
  #2  
Old 02-19-2004, 12:19 PM
meteo's Avatar
meteo meteo is offline
Ultimate Contributor
 
Join Date: Aug 2002
Location: Richardson, Texas
Posts: 1,617
Default

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
__________________
WARNING: Self-Taught Programmer. Use at your own risk.
Standards and Practices
Reply With Quote
  #3  
Old 02-19-2004, 12:21 PM
meteo's Avatar
meteo meteo is offline
Ultimate Contributor
 
Join Date: Aug 2002
Location: Richardson, Texas
Posts: 1,617
Default

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.
__________________
WARNING: Self-Taught Programmer. Use at your own risk.
Standards and Practices
Reply With Quote
  #4  
Old 02-20-2004, 10:49 AM
Squirm's Avatar
Squirm Squirm is offline
Political Coder

Retired Moderator
* Guru *
 
Join Date: Mar 2001
Location: London, England
Posts: 8,037
Default

Is this what you're looking for?
http://msdn.microsoft.com/library/de...mboboxinfo.asp

The COMBOBOXINFO structure has a handle to the child windows of the combo.

Thanks to The Hand.
__________________
Search the forums | Use [vb][/vb] tags | Still IRCing

Last edited by Squirm; 02-20-2004 at 11:04 AM.
Reply With Quote
  #5  
Old 02-20-2004, 11:20 AM
meteo's Avatar
meteo meteo is offline
Ultimate Contributor
 
Join Date: Aug 2002
Location: Richardson, Texas
Posts: 1,617
Default

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!
__________________
WARNING: Self-Taught Programmer. Use at your own risk.
Standards and Practices
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
How to Import List text into a combo box in VB? Majinfaisal General 12 11-28-2003 04:44 PM
combo box additem to list elicaf General 5 07-23-2003 04:38 AM
Intellisense usetheforce2 Miscellaneous Languages 10 10-16-2002 07:48 PM
Combo box List box data insertion Kevalson Database and Reporting 7 09-27-2002 09:03 AM

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->