LxP Posted August 4, 2005 Share Posted August 4, 2005 (edited) While working on a particular problem we found that a window was creating its controls in a random order, and hence the only way to address them was by their position in the window.This UDF will allow you to do just that. Any feedback whatsoever is encouraged! Download: _ControlGetHandleByPos.au3, _ControlGetHandleByPos.txt, _ControlGetHandleByPos_Example.au3 ; ============================================================================== ; ; Function Name: _ControlGetHandleByPos() ; Description: Retrieves the internal handle of a control that matches a ; given position. ; Parameter(s): $sTitle -- the title of the window containing the control ; $sText -- the text of the window containing the control ; $iX -- the X coordinate of the control ; $IY -- the Y coordinate of the control ; Requirement(s): None ; Return Value(s): On success -- returns the control's handle ; On failure -- return and sets @error: ; 1 -- could not find window ; 2 -- could not find control ; Author(s): Alex Peters ; ; ==============================================================================v1.0 (5/Aug/2005):Initial release Edited May 29, 2013 by LxP Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 4, 2005 Moderators Share Posted August 4, 2005 Nice job Alex!! Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
this-is-me Posted August 4, 2005 Share Posted August 4, 2005 What about multiple stacked controls? I know that sometimes Au3Info returns the wrong information considering that it looks at the bottommost control in some windows. Does your UDF suffer from the same problem? Who else would I be? Link to comment Share on other sites More sharing options...
LxP Posted August 5, 2005 Author Share Posted August 5, 2005 At the moment I'm relying on the assumption that a window won't create more than one control with a common (X, Y) position.In the situation where there's more than one control, the function would return the control that's highest in the WinGetClassList() for that window.What would be the best way in your opinion to handle that sort of situation? Return an array of handles? Return a space-separated string of handles perhaps? Link to comment Share on other sites More sharing options...
this-is-me Posted August 7, 2005 Share Posted August 7, 2005 A pipe-separated list appeals to my uses. Is it much of a deal to change it to allow for multiple controls in the same space? Who else would I be? Link to comment Share on other sites More sharing options...
LxP Posted August 7, 2005 Author Share Posted August 7, 2005 Changing the function to output all controls matching a position is easy enough. Do many UDFs delimit their output using vertical bars? I'm guessing that this would mostly be useful for outputting to a combo box or similar? Link to comment Share on other sites More sharing options...
this-is-me Posted August 8, 2005 Share Posted August 8, 2005 Most of the ones I remember either use pipes or @CRLF to separate, but usually not spaces. @CRLF is also acceptable in my case. Who else would I be? Link to comment Share on other sites More sharing options...
Lee Evans Posted August 8, 2005 Share Posted August 8, 2005 When i tried this I got the following error C:\Program Files\AutoIt3\Examples\Controlgethandlebypos.au3 (61) : ==> Expected a "=" operator in assignment statement. I assume that the lines where there are += should infact be = These are line $avUniqueControls[$iLoop][1] += 1 and $iUniqueControls += 1 I am getting zero returned for some controls that exist but they are contained within other controls. Link to comment Share on other sites More sharing options...
LxP Posted August 8, 2005 Author Share Posted August 8, 2005 $avUniqueControls[$iLoop][1] += 1 ··· $iUniqueControls += 1This is shorthand code for:$avUniqueControls[$iLoop][1] = $avUniqueControls[$iLoop][1] + 1 ··· $iUniqueControls = $iUniqueControls + 1Presumably this functionality is only available in the beta. Sorry about that. I don't think that any other parts of the code require the beta.I am getting zero returned for some controls that exist but they are contained within other controls.I am guessing that a control contained in the top-left-hand corner of another control would report a position of (0, 0) regardless of the position of the parent control.If I'm right then I don't think that I can adapt the code to such a situation. I think that you would need to search for the inner control using the position given by AutoIt Window Info.Can anyone please disagree with me on this? Link to comment Share on other sites More sharing options...
Lee Evans Posted August 10, 2005 Share Posted August 10, 2005 No the reason I was getting the zero return for some controls was that your script did not seem to handle Edit 2 etc they were being renamed as Edit 1 I have modified the script slightly and this seemed to work for me expandcollapse popup; ============================================================================== ; ; Function Name: _ControlGetHandleByPos() ; Description: Retrieves the internal handle of a control that matches a ; given position. ; Parameter(s): $sTitle -- the title of the window containing the control ; $sText -- the text of the window containing the control ; $iX -- the X coordinate of the control ; $IY -- the Y coordinate of the control ; Requirement(s): None ; Return Value(s): On success -- returns the control's handle ; On failure -- return and sets @error: ; 1 -- could not find window ; 2 -- could not find control ; Author(s): Alex Peters ; ; ============================================================================== Func _ControlGetHandleByPos($sTitle, $sText, $iX, $iY) Local $hWin, $hControl Local $iControls, $iLoop, $iUniqueControls Local $sClassList, $sClass, $sClassID Local $aiControlPos, $avUniqueControls[1][2] ; Determine that the window exists $hWin = WinGetHandle($sTitle, $sText) If @error Then SetError(2) Return 0 EndIf ; Determine the control classes and total number of controls $sClassList = WinGetClassList($hWin) $iControls = StringLen($sClassList) - StringLen(StringReplace($sClassList, @LF, "")) ReDim $avUniqueControls[$iControls][2] $iUniqueControls = 0 While $sClassList $sClass = StringLeft($sClassList, StringInStr($sClassList, @LF) - 1) $sClassList = StringMid($sClassList, StringLen($sClass) + 2) $sClassID = "" For $iLoop = 0 To $iUniqueControls - 1 If $avUniqueControls[$iLoop][0] = $sClass Then;If there is another button then make button 2 loop $avUniqueControls[$iLoop][1] = $avUniqueControls[$iLoop][1] + 1;Starts at 0 then increments 1 each time a match is made giving button 2 etc $sClassID = $sClass & $avUniqueControls[$iLoop][1];Makes up the correct class ID from above ExitLoop EndIf Next If $sClassID = "" Then;This numbers the first controls eg Edit 1 $avUniqueControls[$iUniqueControls][0] = $sClass $avUniqueControls[$iUniqueControls][1] = 1 $iUniqueControls = $iUniqueControls + 1 $sClassID = $sClass & "1" EndIf ; Determine the position of the control in question $hControl = ControlGetHandle($hWin, "", $sClassID) $aiControlPos = ControlGetPos($hWin, "", $hControl) If ($aiControlPos[0] = $iX And $aiControlPos[1] = $iY) Then _ Return $hControl WEnd ; If we reach this point then no matching control was found SetError(1) Return 0 EndFunc The If Not section did not seem to be working for me so I changed it to If $sClassID = "" and this seems to work. Link to comment Share on other sites More sharing options...
LOBOMINATOR Posted April 24, 2008 Share Posted April 24, 2008 Hello I stumbled over your function _ControlGetHandleByPos(), this seams to me a very important function. I'm currently using the COM component of the latest AutoIt release. When will this function be implemented into the COM lib? Thanks for your help Daniel 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