Sign in to follow this  
Followers 0
BugFix

_MouseTrapCircle

3 posts in this topic

#1 ·  Posted (edited)

_MouseTrapCircle works similar like _MouseTrap, but with trapping inside a circle.

Two additional features:

• With parameter for GUI-handle the given coordinates are used as relative in GUI. By default are absolute coordinates used.

• You can set an timeout to ends trapping without function call. Default ends by call function without parameters.

It's not perfect. Can be pulled out of the circle with a very fast mouse movement.

Edit: Bug fixed in example (diameter instaed radius has used in _PointInCircle)

#Region - TimeStamp
; 2012-07-23 16:52:11 v 0.3
#EndRegion - TimeStamp

#include-once
#Include <WindowsConstants.au3>
#Include <WinAPI.au3>

OnAutoItExitRegister('__MouseTrapCircle_ShutDown')

If Not IsDeclared('$__HC_ACTION') Then Global Const $__HC_ACTION = 0
Global $__hSTUB__MouseProcTrap, $__hMOD_TRAP, $__hHOOK_MOUSE_TRAP
Global $__iXCtr_Trap, $__iYCtr_Trap, $__iRadius_Trap, $__hWND_Trap
Global $__MouseTrapCircle_Started = False, $__Timer_Trap = -1, $__iTimeout_Trap
Global $__iTopBorder, $__iSideBorder
_SystemGetWindowBorder($__iTopBorder, $__iSideBorder)

;===============================================================================
; Function Name....: _MouseTrapCircle
; Description......: Hold the mouse trapped in a circle
; .................: Call without parameters, ends trapping.
; Parameter(s).....: $_iXCentre x-coordinate of the circle center
; .................: $_iYCentre y-coordinate of the circle center
; .................: $_iRadius Radius of the circle
; ........optional.: $_iTimeout Time in ms after trapping ends, without an function call (Default=-1, no timeout)
; ........optional.: $_hWnd  If given: $_iXCentre and $_iYCentre are used as relative to this window.
; .................:             Default: Coordinates are absolut on screen
; Return Value(s)..: Nothing
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _MouseTrapCircle($_iXCentre=-1, $_iYCentre=-1, $_iRadius=-1, $_iTimeout=-1, $_hWnd=-1)
If $_iXCentre = -1 Or $_iYCentre = -1 Or $_iRadius = -1 Then
__MouseTrapCircle_ShutDown()
Else
__MouseTrapCircle_StartUp($_iXCentre, $_iYCentre, $_iRadius, $_iTimeout, $_hWnd)
EndIf
EndFunc ;==>_MouseTrapCircle


#region - Internal functions
;===============================================================================
; Function Name....: __MouseTrapCircle_StartUp
; Description......: Initialize functions
;===============================================================================
Func __MouseTrapCircle_StartUp($_iXCentre, $_iYCentre, $_iRadius, $_iTimeout, $_hWnd)
$__MouseTrapCircle_Started = True
$__iXCtr_Trap = $_iXCentre
$__iYCtr_Trap = $_iYCentre
$__iRadius_Trap = $_iRadius
$__hWND_Trap = $_hWnd
If IsHWnd($__hWND_Trap) Then
Local $aWin = WinGetPos($__hWND_Trap)
$__iXCtr_Trap = $aWin[0] + $__iSideBorder + $__iXCtr_Trap
$__iYCtr_Trap = $aWin[1] + $__iTopBorder + $__iYCtr_Trap
EndIf
If $_iTimeout > 0 Then
$__Timer_Trap = TimerInit()
$__iTimeout_Trap = $_iTimeout
EndIf
; == initialize Callback Function to analyze MOUSE-Message
$__hSTUB__MouseProcTrap = DllCallbackRegister("__MouseProcTrap", "long", "int;wparam;lparam")
$__hMOD_TRAP = _WinAPI_GetModuleHandle(0)
$__hHOOK_MOUSE_TRAP = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($__hSTUB__MouseProcTrap), $__hMOD_TRAP)
EndFunc ;==>__MouseTrapCircle_StartUp

;===============================================================================
; Function Name....: __MouseTrapCircle_ShutDown
; Description......: Close ressources
;===============================================================================
Func __MouseTrapCircle_ShutDown()
If $__MouseTrapCircle_Started Then
_WinAPI_UnhookWindowsHookEx($__hHOOK_MOUSE_TRAP)
DllCallbackFree($__hSTUB__MouseProcTrap)
EndIf
EndFunc ;==>__MouseTrapCircle_ShutDown

;===============================================================================
; Function Name....: __MouseProcTrap
; Description......: Callback mouse procedure
;===============================================================================
Func __MouseProcTrap($nCode, $wParam, $lParam)
If $__Timer_Trap <> -1 And TimerDiff($__Timer_Trap) >= $__iTimeout_Trap Then Return __MouseTrapCircle_ShutDown()
If $nCode <> $__HC_ACTION Then Return _WinAPI_CallNextHookEx($__hHOOK_MOUSE_TRAP, $nCode, $wParam, $lParam)
Local Static $iXComp = -1, $iYComp = -1
Local $iX, $iY, $iXMove, $iYMove, $oldOpt
Local $iDirX = 0, $iDirY = 0
Local $tMSLLHOOKSTRUCT = DllStructCreate("int X;int Y;dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo", $lParam)
Local $tPoint = DllStructCreate('int;int')
$iX = DllStructGetData($tMSLLHOOKSTRUCT, 1)
$iY = DllStructGetData($tMSLLHOOKSTRUCT, 2)
DllStructSetData($tPoint, 1, $iX)
DllStructSetData($tPoint, 2, $iY)
If $iXComp = -1 Then
$iXComp = $iX
$iYComp = $iY
EndIf

Switch $wParam
Case $WM_MOUSEMOVE
If $iX > $iXComp Then
$iDirX = -1
ElseIf $iX < $iXComp Then
$iDirX = 1
EndIf
If $iY > $iYComp Then
$iDirY = -1
ElseIf $iY < $iYComp Then
$iDirY = 1
EndIf
If Not _PointInCircle($iX, $iY, $__iXCtr_Trap, $__iYCtr_Trap, $__iRadius_Trap) Then
$oldOpt = Opt('MouseCoordMode', 1)
MouseMove($iX +($iDirX), $iY +($iDirY), 0)
If IsHWnd($__hWND_Trap) Then
Local $tRect = _WinAPI_GetWindowRect($__hWND_Trap)
If Not _WinAPI_PtInRect($tRect, $tPoint) Then MouseMove($__iXCtr_Trap, $__iYCtr_Trap, 0)
EndIf
Opt('MouseCoordMode', $oldOpt)
Return -1
EndIf

EndSwitch

Return _WinAPI_CallNextHookEx($__hHOOK_MOUSE_TRAP, $nCode, $wParam, $lParam)
EndFunc ;==>__MouseProcTrap

;===============================================================================
; Function Name....: __PointInCircle
; Description......: Calculates whether given position within a circle
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _PointInCircle($_iXPt, $_iYPt, $_iXCircle, $_iYCircle, $_iRadius)
Return ((Sqrt(($_iXCircle-Abs($_iXPt))^2 + ($_iYCircle-Abs($_iYPt))^2)) < $_iRadius)
EndFunc ;==>__PointInCircle

;===============================================================================
; Function Name....: __SystemGetWindowBorder
; Description......: Calculates side and top border of window
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _SystemGetWindowBorder(ByRef $_iTopBorder, ByRef $_iSideBorder)
Local Const $SM_CYCAPTION = 4, $SM_CYEDGE = 46, $SM_CYBORDER = 6, $SM_CXBORDER = 5, $SM_CXEDGE = 45
Local $aMetrics[5][2] = [[$SM_CYCAPTION], [$SM_CYEDGE], [$SM_CYBORDER], [$SM_CXBORDER], [$SM_CXEDGE]]
Local $dll = DllOpen("user32.dll"), $aRet
For $i = 0 To 4
$aRet = DllCall($dll, "int", "GetSystemMetrics", "int", $aMetrics[$i][0])
If IsArray($aRet) Then $aMetrics[$i][1] = $aRet[0]
Next
DllClose($dll)
$_iTopBorder = $aMetrics[0][1] + $aMetrics[1][1] + $aMetrics[2][1]
$_iSideBorder = $aMetrics[3][1] + $aMetrics[4][1]
EndFunc ;==>__SystemGetWindowBorder
#endregion

MouseTrapCircle0.3.au3

MouseTrapCircle_Example.au3

Edited by BugFix

Best Regards BugFix  

Share this post


Link to post
Share on other sites



I like it, but I don't where I should use it.

Maybe sometimes it will be useful to me.

btw:

If _PointInCircle($aMouse[0], $aMouse[1], $aWin[0]+$iSide+150, $aWin[1]+$iTop+150, 90) Then

should be

If _PointInCircle($aMouse[0], $aMouse[1], $aWin[0]+$iSide+150, $aWin[1]+$iTop+150, 45) Then

in example.


Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites

Oops, thank you funkey. The function has worked before with diameter. Than i've changed it to radius, but i've forgotten to make the change in example too.


Best Regards BugFix  

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