Fur Posted February 4, 2005 Share Posted February 4, 2005 I need my script to peer into the listbox of another window, and loop over the contents to decide which one to select. This seemingly simple task is making me bonkers. Hopefully I'm just missing something stupid!! Heeelllp! The help pages (if I'm reading them right) say you can use either the hwnd, or the controlid, or controlref for calling these commands, but that doesn't seem to be the case. Also, all these control commands take a second argument called "text" but I can't for the life of me understand what its used for. All of the examples just pass in an empty string. Example code for window I'm trying to peer into: #include <GUIConstants.au3> GUICreate("Select An Object", 300, 300) Local $list_box = GUICtrlCreateList("", 30, 10) Local $close_button = GUICtrlCreateButton("&Close", 70,250, 60) GUICtrlSetData($list_box, "red|blue|green") GUISetState(@SW_SHOW) While 1 Local $msg = GUIGetMsg() Select Case $msg = $close_button ExitLoop Case $msg = $GUI_EVENT_CLOSE ExitLoop EndSelect WEnd Here's me trying everything possible I can think of. I can get ControlCommand() to work, but it can't loop over the elements. No matter how I try to use ControlListView() it never works.. #include <GuiConstants.au3> Local $title = "Select An Object" Local $win_hwnd = WinActivate($title) Local $focus = ControlGetFocus($title) Local $list = _GuiCtrlGetFocus($title) Local $hwnd = ControlGetHandle($title, "", ControlGetFocus($title)) ;MsgBox(0, "", ControlListView($title, "", $focus, "GetItemCount") ) ;MsgBox(0, "", ControlListView($title, "", $focus, "GetText", 1, 0) ) ;MsgBox(0, "", ControlListView($title, "", $list, "GetItemCount") ) ;MsgBox(0, "", ControlListView($title, "", $list, "GetText", 1, 0) ) ;MsgBox(0, "", ControlListView($title, "", $hwnd, "GetItemCount") ) ;MsgBox(0, "", ControlListView($title, "", $hwnd, "GetText", 1, 0) ) MsgBox(0, "", ControlCommand($title, "", $focus, "GetCurrentSelection") ) ;MsgBox(0, "", ControlListView($title, "", $focus, "GetSelected") ) ;ControlCommand($title, "", $list, "AddString", "Foopy") ; works ControlCommand($title, "", $focus, "AddString", "Foopy") ControlCommand($title, "", $focus, "SelectString", "red") ;ControlCommand($title, "", $hwnd, "AddString", "Foopy") Exit Func _GuiCtrlGetFocus($GuiRef) Local $hwnd = ControlGetHandle($GuiRef, "", ControlGetFocus($GuiRef)) Local $result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hwnd) Return $result[0] EndFunc Link to comment Share on other sites More sharing options...
CyberSlug Posted February 4, 2005 Share Posted February 4, 2005 - It appears that ControlGetFocus doesn't return the right value.... - ControlListView is not designed for ListBoxes. - ControlCommands for ListBoxes are limited; there is no direct command to read all the items in the list.... When ControlCommand was designed, it was assumed you would know what is already in the list.... You can select each item and read the text using the following: Local $title = "Select An Object" Local $control = "ListBox1" $i = 0 While 1 ControlCommand($title,"", $control, "SetCurrentSelection", $i) If @error Then ExitLoop $item = ControlCommand($title,"", $control, "GetCurrentSelection") MsgBox(4096, $i, $item) $i = $i + 1 WEnd Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig! Link to comment Share on other sites More sharing options...
Fur Posted February 4, 2005 Author Share Posted February 4, 2005 ok, so i'm not as crazy as i thought i was then. powers that be: is it too late to sneak something to get all the elements out of a listbox? even if its just a pipe delimited list of them all? what about the mysterious 'text' argument? any clues? Link to comment Share on other sites More sharing options...
CyberSlug Posted February 4, 2005 Share Posted February 4, 2005 what about the mysterious 'text' argument? any clues?<{POST_SNAPBACK}>It is used to tell the difference between windows that have the same title.For example, you might have a program that displays a message box that either has the text "Success" or "Error." If the title/size/etc. are the same, you need can use the text parameter to tell the difference.$title = "Sample Info Dialog"WinWait($title)If WinExists($title, "Success!") Then; goodElseIf WinExists($title, "Error: Could not copy files."); badElseIf WinExists($title, "Error: Unknown error."); really badElse; whateverEndIf Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig! Link to comment Share on other sites More sharing options...
Fur Posted February 10, 2005 Author Share Posted February 10, 2005 I made a C function to put the pipe delimited contents into a string that I can grab via a DLLCall. This is using a static memory space, so it would not be thread/process safe. If anyone has any advice on how to have AutoIt allocate a string buffer that could be passed into this, I would appreciate hearing how. // given the hwnd for a listbox, put the contents into a pipe delimited string // TODO: NOT thread/process safe // TODO: NOT checking for buffer overruns const char *ExtractListContents(HWND hwnd) { static char results[4096]; *results = '\0'; long count = SendMessage(hwnd, LB_GETCOUNT, 0, 0); for (long i = 0; i < count; ++i) { char item[256] = ""; SendMessage(hwnd, LB_GETTEXT, i, (long) item); if (i == 0) strcpy(results, item); else { strcat(results, "|"); strcat(results, item); } } return results; } Link to comment Share on other sites More sharing options...
this-is-me Posted February 10, 2005 Share Posted February 10, 2005 Just to let you know, you can already SendMessage(hwnd, LB_GETCOUNT, 0, 0) using plain dllcall... Who else would I be? Link to comment Share on other sites More sharing options...
Fur Posted February 10, 2005 Author Share Posted February 10, 2005 Yes, but can you call LB_GETTEXT in that same manner? That's the tricky part. Link to comment Share on other sites More sharing options...
Valik Posted February 10, 2005 Share Posted February 10, 2005 (edited) Not tricky at all:Local $aCount = DllCall("user32.dll", "int", "SendMessage", "hwnd", $hWnd, "int", $LB_GETCOUNT, "int", 0, "int" 0) Local $sResult = "" For $i = 0 To $aCount[0]-1 Local $aTmp = DllCall("user32.dll", "int", "SendMessage", "hwnd", $hWnd, "int", $LB_GETTEXT', "int", $i, "str", "") $sResult = $sResult & "|" & $aTmp[4] Next $sResult = StringTrimLeft($sResult, 1); Trim a leading pipeThats off the top of my head and if its not working, it should be close enough to give you an idea how it should be.Edit: Fixed mistake. Edited February 10, 2005 by Valik Link to comment Share on other sites More sharing options...
Fur Posted February 10, 2005 Author Share Posted February 10, 2005 How/where is the memory for that last str argument allocated? You're just passing in "" which by itself is not going to be long enough to hold the result. Does AutoIt do some kind of padding behind the scenes? By how much? Link to comment Share on other sites More sharing options...
Valik Posted February 10, 2005 Share Posted February 10, 2005 65535 bytes. And yes, when you tell it that the function expects a "str", then it allocates that buffer. 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