alext Posted November 16, 2009 Share Posted November 16, 2009 Maybe this question has already been answered somewhere, (i haven't found it though) ... in case it did, please just point me to the right direction and I will figure it out. Here is my problem... I have a listbox with the following properties >>>> Control <<<< Class: ListBox Instance: 4 ClassnameNN: ListBox4 Advanced (Class): [CLASS:ListBox; INSTANCE:4] ID: 302 Text: Position: 713, 83 Size: 300, 406 ControlClick Coords: 98, 173 Style: 0x50310121 ExStyle: 0x00000204 Handle: 0x00270130 As you can see the instance nr is 4 and the id is 302... so the following lines of code should return the same handle, but they don't. When I use the instance, I do get the correct handle... Local $hSectionGrid = ControlGetHandle("Client","","[iD:302]") ConsoleWrite("SectionGrid: " & $hSectionGrid &@CR) Local $hSectionGrid_1 = ControlGetHandle("Client","","[CLASS:ListBox;INSTANCE:4]") ConsoleWrite("SectionGrid: " & $hSectionGrid_1 &@CR) The reason I need this to work is because I have a "hidden" control...and I can't get the instance nr of that control, just the ID... but when I try getting it's handle by means of the ID...it just doesn't return me the correct handle. Can anybody tell me what I'm doing wrong here? Thanks for the help! Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 16, 2009 Share Posted November 16, 2009 (edited) This works: #include <GuiConstantsEx.au3> #include <WinAPI.au3> GUICreate("Client", 300, 380) For $n = 1 To 10 GUICtrlCreateList("List: " & $n, 20, 20 + (($n - 1) * 30), 200, 20) Next $idButton_1 = GUICtrlCreateButton("Get Handles", 100, 330, 100, 30) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $idButton_1 For $n = 1 To 10 $sMsg = "Instance = " & $n & ":" & @CRLF $hList = ControlGetHandle("Client", "", "[CLASS:ListBox; Instance:" & $n & "]") $sMsg &= @TAB & "HWND (by Class/Instance) = " & $hList & @CRLF $idList = _WinAPI_GetDlgCtrlID($hList) $sMsg &= @TAB & "ControlID = " & $idList & "; Type = " & VarGetType($idList) & @CRLF $idListInt = Int(String($idList)) $sMsg &= @TAB & "ControlID (Int) = " & $idListInt & "; Type = " & VarGetType($idListInt) & @CRLF $hList = ControlGetHandle("Client", "", "[ID:" & $idListInt & "]") $sMsg &= @TAB & "HWND (by ControlID) = " & $hList & @CRLF ConsoleWrite($sMsg) Next EndSwitch WEnd I noticed while trying it that in some cases passing an invalid control ID (0) caused the handle to the last control created (the button in GUI above) to be returned. If you are passing the control ID in a variable, make sure it is an integer and the correct ID. Note in my demo where the ControlID returned from _WinAPI_GetDlgCtrlId() has to be converted before it's used. Edit: Changed handling of $idList to avoid dereferencing a pointer. The pointer only comes up due to a bug in the Production version. It is returned as a correct INT32 type in the current Beta. Edited November 16, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
alext Posted November 17, 2009 Author Share Posted November 17, 2009 This works: #include <GuiConstantsEx.au3> #include <WinAPI.au3> GUICreate("Client", 300, 380) For $n = 1 To 10 GUICtrlCreateList("List: " & $n, 20, 20 + (($n - 1) * 30), 200, 20) Next $idButton_1 = GUICtrlCreateButton("Get Handles", 100, 330, 100, 30) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $idButton_1 For $n = 1 To 10 $sMsg = "Instance = " & $n & ":" & @CRLF $hList = ControlGetHandle("Client", "", "[CLASS:ListBox; Instance:" & $n & "]") $sMsg &= @TAB & "HWND (by Class/Instance) = " & $hList & @CRLF $idList = _WinAPI_GetDlgCtrlID($hList) $sMsg &= @TAB & "ControlID = " & $idList & "; Type = " & VarGetType($idList) & @CRLF $idListInt = Int(String($idList)) $sMsg &= @TAB & "ControlID (Int) = " & $idListInt & "; Type = " & VarGetType($idListInt) & @CRLF $hList = ControlGetHandle("Client", "", "[ID:" & $idListInt & "]") $sMsg &= @TAB & "HWND (by ControlID) = " & $hList & @CRLF ConsoleWrite($sMsg) Next EndSwitch WEnd I noticed while trying it that in some cases passing an invalid control ID (0) caused the handle to the last control created (the button in GUI above) to be returned. If you are passing the control ID in a variable, make sure it is an integer and the correct ID. Note in my demo where the ControlID returned from _WinAPI_GetDlgCtrlId() has to be converted before it's used. Edit: Changed handling of $idList to avoid dereferencing a pointer. The pointer only comes up due to a bug in the Production version. It is returned as a correct INT32 type in the current Beta. mmmkay.... the thing is... I don't have an INSTANCE for my object...I only have the ID. So I was trying to get a handle to a control by it's ID. But to make sure I'm not wasting my time I tried getting a handle to a control for which I did know it's INSTANCE and it's ID. (just as a test) ControlGetHandle("Client","","[iD:302]") and ControlGetHandle("Client","","[CLASS:ListBox;INSTANCE:4]") should return me the same handle...as you can see from the control info ... ID 302 and LISTBOX of Instance 4 are one and the same... And somehow the handle that I get by an ID is not the same as the one I get by the INSTANCE. I'm not creating objects (controls) ... I need to be able to control an existing object in an application written in ... I dunno...I don't care. So basically with an Info tool I get the ID and Instance of a control... and with ControlGetHandle I want a handle (preferably the same handle ) once with it's ID and once with it's Instance. Unfortunatly this does not happen... and I don't know why... It's driving me crazy since I need to get a handle to a control from wich I don't have the INSTANCE...I think it's hidden or something... Anyway...I appreciate your help!! Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 17, 2009 Share Posted November 17, 2009 I was only trying to demonstrate that everything worked as advertised in a demo GUI that we could all work with. There was a minor detour into a bug that is irrelevant to this topic. The real point was that we can't reproduce your symptoms. What is the app producing that GUI? If it's something common, we might be able to see it. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
alext Posted November 18, 2009 Author Share Posted November 18, 2009 I was only trying to demonstrate that everything worked as advertised in a demo GUI that we could all work with. There was a minor detour into a bug that is irrelevant to this topic. The real point was that we can't reproduce your symptoms. What is the app producing that GUI? If it's something common, we might be able to see it. The problem is that this utility I'm trying to control was written sometimes around 200BC or something... it's so ancient I think I can get it sold to an antique store...Unfortunatly we don't have the code for this tool (as the programmer most likely sat next to Jezus in highschool).And I can't give this program out ... kinda contains sensitive info about our company... so I guess we're just SOL.So... I'm not giving you anything to help me am I? Sorry man!All I know is that I have a ListBox with another ListBox inside of it ... don't know how this works but I have a Info utility that has recognized them (the AI Window Info utility didn't recognize the inner ListBox). The Instance ID for the outer ListBox are in both Info utilities the same... so I guess it's working allright.So now I have an ID for the inner (hidden?) ListBox... and I would like to get a handle to it.Maybe this will be fixed (somehow) in a future release of AutoIt. Thanks anyway!! Link to comment Share on other sites More sharing options...
bo8ster Posted November 18, 2009 Share Posted November 18, 2009 You will always be able to get the instance using WinGetClassList(). This is how the instance count is generated within AutoIt. You can display the output in an array to see what is going on. Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic] Link to comment Share on other sites More sharing options...
alext Posted November 18, 2009 Author Share Posted November 18, 2009 You will always be able to get the instance using WinGetClassList(). This is how the instance count is generated within AutoIt. You can display the output in an array to see what is going on.WinGetClassList() only gives me the names of the classes... I don't see the Instance...or is the Instance ID the (0 based) index from the control (from the bottom)? Link to comment Share on other sites More sharing options...
alext Posted November 18, 2009 Author Share Posted November 18, 2009 This works: #include <GuiConstantsEx.au3> #include <WinAPI.au3> GUICreate("Client", 300, 380) For $n = 1 To 10 GUICtrlCreateList("List: " & $n, 20, 20 + (($n - 1) * 30), 200, 20) Next $idButton_1 = GUICtrlCreateButton("Get Handles", 100, 330, 100, 30) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $idButton_1 For $n = 1 To 10 $sMsg = "Instance = " & $n & ":" & @CRLF $hList = ControlGetHandle("Client", "", "[CLASS:ListBox; Instance:" & $n & "]") $sMsg &= @TAB & "HWND (by Class/Instance) = " & $hList & @CRLF $idList = _WinAPI_GetDlgCtrlID($hList) $sMsg &= @TAB & "ControlID = " & $idList & "; Type = " & VarGetType($idList) & @CRLF $idListInt = Int(String($idList)) $sMsg &= @TAB & "ControlID (Int) = " & $idListInt & "; Type = " & VarGetType($idListInt) & @CRLF $hList = ControlGetHandle("Client", "", "[ID:" & $idListInt & "]") $sMsg &= @TAB & "HWND (by ControlID) = " & $hList & @CRLF ConsoleWrite($sMsg) Next EndSwitch WEnd I noticed while trying it that in some cases passing an invalid control ID (0) caused the handle to the last control created (the button in GUI above) to be returned. If you are passing the control ID in a variable, make sure it is an integer and the correct ID. Note in my demo where the ControlID returned from _WinAPI_GetDlgCtrlId() has to be converted before it's used. Edit: Changed handling of $idList to avoid dereferencing a pointer. The pointer only comes up due to a bug in the Production version. It is returned as a correct INT32 type in the current Beta. What if I know the handle of the object from my Info utility? How can i use it to control the object? Something like $Handle = 0x00350146 _GuiCtrlListBox.gettext($Handle) But this doesn't work.... Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 18, 2009 Share Posted November 18, 2009 All I know is that I have a ListBox with another ListBox inside of it ... don't know how this works but I have a Info utility that has recognized them (the AI Window Info utility didn't recognize the inner ListBox). The Instance ID for the outer ListBox are in both Info utilities the same... so I guess it's working allright. So now I have an ID for the inner (hidden?) ListBox... and I would like to get a handle to it. Maybe this will be fixed (somehow) in a future release of AutoIt. Thanks anyway!!Well now, that's interesting. Rather than one inside the other, it may just be one stacked on top of the other by it's X/Y coordinates. Controls can be "stacked" on GUI just like windows on you desktop, and AU3Info.exe only returns the info for the one at the top of stack (z-order is the term of art). WinGetClassList() only gives me the names of the classes... I don't see the Instance...or is the Instance ID the (0 based) index from the control (from the bottom)?Instance numbers are 1-based. If you have the class, you can generate ClassNameNN by trying numbers from 1 to 99 as "ListBox1" thru "ListBox99", or use advanced control IDs as "[CLASS:ListBox; INSTANCE:1]" thru "[CLASS:ListBox; INSTANCE:99]". What if I know the handle of the object from my Info utility? How can i use it to control the object? Something like $Handle = 0x00350146 _GuiCtrlListBox.gettext($Handle) But this doesn't work....You can force an HWND type by: $Handle = Hwnd(0x00350146) The problem is, you would have to rediscover and reenter the literal handle value every time you ran the program. Handles to windows and controls (controls are just little child windows to the OS) remain fixed for the life of the current instance, but will be different each time they are recreated (running the app again). Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
bo8ster Posted November 18, 2009 Share Posted November 18, 2009 (edited) WinGetClassList() only gives me the names of the classes... I don't see the Instance...or is the Instance ID the (0 based) index from the control (from the bottom)?let me demonstrate. The array returned by WinGetClassList() may look something like this..ListBoxButtonListViewListBoxButton...Count how many times the same class appears so you get something like ...ListBox1Button1ListView1ListBox2Button2You can sort the array for ease.See here for more info _ControlGetClassnameNN() Edited November 18, 2009 by bo8ster Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic] Link to comment Share on other sites More sharing options...
alext Posted November 19, 2009 Author Share Posted November 19, 2009 I appreciate all of you help guys... but it doesn't seem to work like I would like it to. My info tool shows me 2 ListBoxes (on top of each other or inside of each other) but I starting to think it also might have multiple columns...and from what I've read on this forum, AutoIt does not support ListBoxes with multiple columns. I think we're just SOL Anyway! Thanks again! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now