Sign in to follow this  
Followers 0
Kohr

Help with x/y coords of controls

4 posts in this topic

Hello all. I am using AutoIt much more in my job now (great tool btw) and I would like some help (point me in a direction) with the following code.

Basically I am trying to create a tool that will:

1. Read all ControlIDs and display them in a GUI (todo)

2. Based on what is select, I want to draw boxes around the control (current project)

3. Save this image in Word or somewhere (todo)

My issue is that I can get the boxes drawn around all the controls but my coords are off. It works fine with our company application but I wanted it to work with other applications as well. The example I am using is for the calculator. All of my boxes look correct on the x axis but y is too high. Any suggestions would be appreciated.

Also some pieces of code I got out of other scripts which helped with this idea. Did I give proper credit in the correct places?

Thanks.

Kohr

; Portions written by JdeB, Valuater, Alex Peters

Opt("WinTitleMatchMode", 2)

$gCurrentWindow = "Calc"
WinActivate($gCurrentWindow)

$ControlIds = WinGetControlIDs($gCurrentWindow)
ConsoleWrite ("TotalControlIDs:" & $ControlIds[0] & @CRLF)
For $i = 1 To $ControlIds[0]
    $ShortName = StringLeft($ControlIds[$i], 3)
    If $ShortName = "Afx" Then
        ContinueLoop
    EndIf
    If $ShortName = "Too" Then
        ContinueLoop
    EndIf
    If $ShortName = "msc" Then
        ContinueLoop
    EndIf
    
;fDrawBox($gCurrentWindow, $ControlIds[$i], 0x0000ff, 2, 3, 47)
    fDrawBox($gCurrentWindow, $ControlIds[$i], 0x0000ff, 2)
Next

Func fDrawBox($Window, $Control, $LineColor, $LineWidth, $OffsetX = 0, $OffsetY = 0)
    $size = WinGetPos($Window)
    $ControlPos = ControlGetPos($Window, "", $Control)
    $ControlPos[0] = $ControlPos[0] + $size[0] + $OffsetX
    $ControlPos[1] = $ControlPos[1] + $size[1] + $OffsetY
    
    $dllUser32 = DllOpen("user32.dll")
    $dllGdi32 = DllOpen("gdi32.dll")
    For $i = 1 To 4
        Switch $i
            Case 1;top side
                ConsoleWrite("1")
                $x1 = $ControlPos[0]
                $y1 = $ControlPos[1]
                $x2 = $ControlPos[0] + $ControlPos[2]
                $y2 = $ControlPos[1]
            Case 2;left side
                ConsoleWrite("2")
                $x1 = $ControlPos[0]
                $y1 = $ControlPos[1]
                $x2 = $ControlPos[0]
                $y2 = $ControlPos[1] + $ControlPos[3]
            Case 3;right side
                ConsoleWrite("3")
                $x1 = $ControlPos[0] + $ControlPos[2]
                $y1 = $ControlPos[1]
                $x2 = $ControlPos[0] + $ControlPos[2]
                $y2 = $ControlPos[1] + $ControlPos[3]
            Case 4;bottom side
                ConsoleWrite("4")
                $x1 = $ControlPos[0]
                $y1 = $ControlPos[1] + $ControlPos[3]
                $x2 = $ControlPos[0] + $ControlPos[2]
                $y2 = $ControlPos[1] + $ControlPos[3]
        EndSwitch
    ;Below written by: Author JdeB, Co-Author Valuater
        $hd = DllCall($dllUser32, "int", "GetDC", "hwnd", 0)
        $pen = DllCall($dllGdi32, "int", "CreatePen", "int", 0, "int", $LineWidth, "int", $LineColor)
        DllCall($dllGdi32, "int", "SelectObject", "int", $hd[0], "int", $pen[0])
        DllCall($dllGdi32, "int", "MoveToEx", "hwnd", $hd[0], "int", $x1, "int", $y1, "int", 0)
        DllCall($dllGdi32, "int", "LineTo", "hwnd", $hd[0], "int", $x2, "int", $y2)
        DllCall($dllUser32, "int", "ReleaseDC", "hwnd", 0, "int", $hd[0])
    Next
    DllClose($dllUser32)
    DllClose($dllGdi32)
EndFunc  ;==>fDrawBox

Func fDrawBoxCoord($Left, $Top, $Right, $Bottom, $LineColor, $LineWidth)
    $dllUser32 = DllOpen("user32.dll")
    $dllGdi32 = DllOpen("gdi32.dll")
    For $i = 1 To 4
        Switch $i
            Case 1;top side
                ConsoleWrite("1")
                $x1 = $Left
                $y1 = $Top
                $x2 = $Right
                $y2 = $Top
            Case 2;left side
                ConsoleWrite("2")
                $x1 = $Left
                $y1 = $Top
                $x2 = $Left
                $y2 = $Bottom
            Case 3;right side
                ConsoleWrite("3")
                $x1 = $Right
                $y1 = $Top
                $x2 = $Right
                $y2 = $Bottom
            Case 4;bottom side
                ConsoleWrite("4")
                $x1 = $Left
                $y1 = $Bottom
                $x2 = $Right
                $y2 = $Bottom
        EndSwitch
    ;Below written by: Author JdeB, Co-Author Valuater
        $hd = DllCall($dllUser32, "int", "GetDC", "hwnd", 0)
        $pen = DllCall($dllGdi32, "int", "CreatePen", "int", 0, "int", $LineWidth, "int", $LineColor)
        DllCall($dllGdi32, "int", "SelectObject", "int", $hd[0], "int", $pen[0])
        DllCall($dllGdi32, "int", "MoveToEx", "hwnd", $hd[0], "int", $x1, "int", $y1, "int", 0)
        DllCall($dllGdi32, "int", "LineTo", "hwnd", $hd[0], "int", $x2, "int", $y2)
        DllCall($dllUser32, "int", "ReleaseDC", "hwnd", 0, "int", $hd[0])
    Next
    DllClose($dllUser32)
    DllClose($dllGdi32)
EndFunc  ;==>fDrawBoxOld

Func WinGetControlIDs($sTitle, $sText = '')
;Code from Alex Peters, 4/3/2006
    Local $avClasses[1], $iCounter, $sClasses, $sClassStub, $sClassStubList
    
; Request an unnumbered class list.
    $sClassStubList = WinGetClassList($sTitle, $sText)
    
; Return an empty response if no controls exist.
; Additionally set @Error if the specified window was not found.
    If $sClassStubList = '' Then
        If @error Then SetError(1)
        $avClasses[0] = 0
        Return $avClasses
    EndIf
    
; Prepare an array to hold the numbered classes.
    ReDim $avClasses[StringLen($sClassStubList) - _
            StringLen(StringReplace($sClassStubList, @LF, '')) + 1]
    
; The first element will contain a count.
    $avClasses[0] = 0
    
; Count each unique class, enumerate them in the array and remove them from
; the string.
    Do
        $sClassStub = _
                StringLeft($sClassStubList, StringInStr($sClassStubList, @LF))
        $iCounter = 0
        While StringInStr($sClassStubList, $sClassStub)
            $avClasses[0] += 1
            $iCounter += 1
            $avClasses[$avClasses[0]] = _
                    StringTrimRight($sClassStub, 1) & $iCounter
            $sClassStubList = _
                    StringReplace($sClassStubList, $sClassStub, '', 1)
        WEnd
    Until $sClassStubList = ''
    
    Return $avClasses
    
EndFunc  ;==>WinGetControlIDs

Share this post


Link to post
Share on other sites



Use Opt('MouseCoordMode', 2) ... Since your using ControlGetPos() to get their positions.


[center]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.[/center]

Share this post


Link to post
Share on other sites

Smoke I tried that setting and it didn't effect my code.

The code basically works as follows to draw boxes around objects. (I want to draw the boxes around objects mainly so I can highlight important data on a screen to either print or capture. We currently manually print 100's of screen images and highlight the important data and this will hopefully replace that.)

1. Get all of the ControlNameNN for a window. In the code example I use it against the calculator.

2. Get the control position of an object.

3. Get the window position.

4. Then I draw 4 lines around the object using the position from 2 and 3. Well that is what I am trying to achieve.

Running this against the calculator all the object have the lines drawn correctly they are just too far up on the window.

I could not get it to work without using the window position to help wth drawing the lines. My initial thought was I would just use the object position but I think drawing lines on the screen is only based on screen coords and not the window.

Any input or advice on this would be great.

Kohr

Share this post


Link to post
Share on other sites

Did you made any progress? That's exactly the point I'm at now. I found Larrys OutlineControl but it does not work on Scite and Explorer -- if I did no big mistake. So I thought I may use his DrawRectangle to do this job, but I'm just kinda stuck right now. Seems like it works if add twice the titlebar-height that's stored in the registry. But I don't want to use that since borderless windows would not be painted/outlined correctly. I thought of moving the pointer to the upper corner of the window and get it back asap, but I don't really like that idea.

Maybe I'll toy with OutlineControl to see what does not work here.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0