Jump to content
Sign in to follow this  
Deye

RectRgn GetPos

Recommended Posts

Hi,

I'm trying to figure out how can I get the drawn rectangle Positions as if  it was a control placed on the main gui once PRIMARYDOWN mouse is up used with ControlGetPos (for instance)

I dont understand how i may get the positions of the rectangle and make it relative to the gui

in the example I'm trying to get a positive return if I will draw the rectangle over the button and false in the rectangle is drawn else where @not over the button

Thanks

#include <GUIConstants.au3>
#include <WinAPISysWin.au3>
#include <WinAPIGdi.au3>
#include <Misc.au3>

$hGui = GUICreate("Sample GUI", 406, 346)

$IdButton3 = GUICtrlCreateButton("Button_3", 68, 89, 65, 30)

GUISetState(@SW_SHOW)
Local $hDLL = DllOpen("user32.dll")


While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_PRIMARYDOWN
            _drawRect()
        Case $GUI_EVENT_CLOSE
            DllClose($hDLL)
            Exit
    EndSwitch
WEnd


Func _drawRect()
    $GUIPos = WinGetPos($hGui, "")

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST, $hGui)
    GUISetBkColor(0x000000)

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    While _IsPressed("01", $hDLL)
        $aMouse_Pos = MouseGetPos()
        $hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
        $hMask = _WinAPI_CreateRectRgn($iX1, $aMouse_Pos[1], $aMouse_Pos[0], $aMouse_Pos[1] + 1)   ; Bottom of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]) ; Left of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1) ; Top of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($aMouse_Pos[0], $iY1, $aMouse_Pos[0] + 1, $aMouse_Pos[1])  ; Right of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        ; Set overall region
        _WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)
        If WinGetState($hRectangle_GUI) < 15 Then GUISetState()
    WEnd
    ConsoleWrite(_hWnd_IsVisible($IdButton3, $hRectangle_GUI) & @LF)
    
    GUIDelete($hRectangle_GUI)
EndFunc   ;==>_drawRect

Func _hWnd_IsVisible($hWnd, $hWnd_ParentGui = 0)

    Local $tRect_hWnd = _WinAPI_GetWindowRect($hWnd)
    Local $h_Rgn_hWnd = _WinAPI_CreateRectRgn(DllStructGetData($tRect_hWnd, 1), DllStructGetData($tRect_hWnd, 2), DllStructGetData($tRect_hWnd, 3), DllStructGetData($tRect_hWnd, 4))

    Local $tRect_hWndPrev, $h_Rgn_hWndPrev

    Local $aList = WinList()

    For $i = 1 To $aList[0][0]
        If $aList[$i][1] = $hWnd Then ExitLoop
        If BitAND(WinGetState($aList[$i][1]), 2) And $aList[$i][1] <> $hWnd_ParentGui Then
            $tRect_hWndPrev = _WinAPI_GetWindowRect($aList[$i][1])
            $h_Rgn_hWndPrev = _WinAPI_CreateRectRgn(DllStructGetData($tRect_hWndPrev, 1), DllStructGetData($tRect_hWndPrev, 2), DllStructGetData($tRect_hWndPrev, 3), DllStructGetData($tRect_hWndPrev, 4))
            _WinAPI_CombineRgn($h_Rgn_hWnd, $h_Rgn_hWnd, $h_Rgn_hWndPrev, $RGN_DIFF)
            _WinAPI_DeleteObject($h_Rgn_hWndPrev)
        EndIf
    Next

    Local $iRes = _WinAPI_GetRgnBox($h_Rgn_hWnd, $tRect_hWnd)
    _WinAPI_DeleteObject($h_Rgn_hWnd)

    Switch $iRes
        Case 1 ; $NULLREGION
            Return 0
        Case 2 ; $SIMPLEREGION
            Return 1
        Case 3 ; $COMPLEXREGION
            Return 1
        Case Else ; 0 = Error
            Return -1
    EndSwitch

EndFunc   ;==>_hWnd_IsVisible

 

Edited by Deye

Share this post


Link to post
Share on other sites

Just updated my question .. The example now includes @kafu's example from here in hopes that it can be worked out in the suggested way 

the example is roughly put there are many things that aren't getting properly considered ( I know)

in the example I'm trying to get a positive return if I will draw the rectangle over the button and false in the rectangle is drawn else where @not over the button

if not and this  can get  done in another way, Please suggest 

Thanks

 

Edited by Deye

Share this post


Link to post
Share on other sites

Try this  - works for me :

#include <Constants.au3>
#include <GUIConstants.au3>
#include <WinAPISysWin.au3>
#include <WinAPIGdi.au3>
#include <Misc.au3>
#include <WinAPIConv.au3>

$hGui = GUICreate("Sample GUI", 406, 346)

$IdButton3 = GUICtrlCreateButton("Button_3", 68, 89, 65, 30)

GUISetState(@SW_SHOW)
Local $hDLL = DllOpen("user32.dll"), $aPos


While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_PRIMARYDOWN
            $aPos = _drawRect()
            MsgBox ($MB_SYSTEMMODAL,"",Check ($hGui, $IdButton3, $aPos))
        Case $GUI_EVENT_CLOSE
            DllClose($hDLL)
            Exit
    EndSwitch
WEnd


Func _drawRect()
    $GUIPos = WinGetPos($hGui, "")

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST, $hGui)
    GUISetBkColor(0x000000)

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    While _IsPressed("01", $hDLL)
        $aMouse_Pos = MouseGetPos()
        $hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
        $hMask = _WinAPI_CreateRectRgn($iX1, $aMouse_Pos[1], $aMouse_Pos[0], $aMouse_Pos[1] + 1)   ; Bottom of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]) ; Left of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1) ; Top of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($aMouse_Pos[0], $iY1, $aMouse_Pos[0] + 1, $aMouse_Pos[1])  ; Right of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        ; Set overall region
        _WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)
        If WinGetState($hRectangle_GUI) < 15 Then GUISetState()
    WEnd
    GUIDelete($hRectangle_GUI)
    Return StringSplit ($iX1 & "/" & $iY1 & "/" & $aMouse_Pos[0] & "/" & $aMouse_Pos[1],"/", $STR_NOCOUNT)
EndFunc   ;==>_drawRect

Func Check ($hWnd, $idCtrl, $aPos)
    Local $tPoint = DllStructCreate("int X;int Y")
    DllStructSetData($tPoint, "X", $aPos[0])
    DllStructSetData($tPoint, "Y", $aPos[1])
    _WinAPI_ScreenToClient($hWnd, $tPoint)
    $aPos[0] = DllStructGetData($tPoint, "X")
    $aPos[1] = DllStructGetData($tPoint, "Y")
    DllStructSetData($tPoint, "X", $aPos[2])
    DllStructSetData($tPoint, "Y", $aPos[3])
    _WinAPI_ScreenToClient($hWnd, $tPoint)
    $aPos[2] = DllStructGetData($tPoint, "X")
    $aPos[3] = DllStructGetData($tPoint, "Y")
    Local $idPos = ControlGetPos ($hWnd, "", $idCtrl)
    Return $idPos[0] >= $aPos[0] and $idPos[1] >= $aPos[1] and $idPos[0]+$idPos[2]-1 <= $aPos[2] and $idPos[1]+$idPos[3]-1 <= $aPos[3]
EndFunc

 

Share this post


Link to post
Share on other sites

@Nine Not quite there: if you draw  a  rectangle  anywhere over a control it should return true !!

i tried doing it your way and it seemed to work for a while till I tried drawing the rectangle in a reversed way then the calculations need to change apparently but didn't get to make it work

;.......>
    Local $idPos = ControlGetPos ($hWnd, "", $idCtrl)
    If $idPos[0] > $aPos[2] Then
    ElseIf $aPos[2] > $idPos[0] + $idPos[2] And $aPos[0] > $idPos[0] + $idPos[2] Then
    Else
        If $aPos[3] + ($aPos[1] - $aPos[3]) < $idPos[1] Or $aPos[3] > $idPos[1] + $idPos[3] Then
        Else
            Return True
        EndIf
    EndIf
    Return False

Edit: maybe this will do it:

;.......>
    Local $idPos = ControlGetPos ($hWnd, "", $idCtrl)
    $RectR = $aPos[2] > $aPos[0] ? $aPos[2] : $aPos[0]
    $RectL = ($RectR = $aPos[2] ? $aPos[0] : $aPos[2])
    $RectT = $aPos[3] < $aPos[1] ? $aPos[3] : $aPos[1]
    $RectB = ($RectT = $aPos[3] ? $aPos[1] : $aPos[3])

    Local $idPos = ControlGetPos($hWnd, "", $idCtrl)
    If $idPos[0] > $RectR Then
    ElseIf $RectR > $idPos[0] + $idPos[2] And $RectL > $idPos[0] + $idPos[2] Then
    Else
        If $RectT + ($RectB - $RectT) < $idPos[1] Or $RectT > $idPos[1] + $idPos[3] Then
        Else
            Return True
        EndIf
    EndIf
    Return False
EndFunc   ;==>Check

maybe if we could get the rect pointers of the $hRectangle_GUI  relative to the main gui  it be easier to make it work with kafu's example
 

 

Edited by Deye

Share this post


Link to post
Share on other sites
5 hours ago, Deye said:

if you draw  a  rectangle  anywhere over a control it should return true !!

Ah, I thought the rectangle need to cover all the control, then change the return to this :

Return $idPos[0] <= $aPos[2] And $idPos[1] <= $aPos[3] And $idPos[0] + $idPos[2] - 1 >= $aPos[0] And $idPos[1] + $idPos[3] - 1 >= $aPos[1]

Makes it more readable. 

Ya,  I forgot about drawing the rectangle from bottom to top or right to left.  Good catch :)

 

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...