Two points define a straight line, three points define a circle.
CursorOnCurve is controlled using the RControl and RButton keys:
When the cursor is at point 1, press the key combination RControl + RButton and release RControl. Now move the cursor to point 2 and release RButton.
The cursor is now bound to the straight line defined in this way, a state that can be switched off/on using RControl.
If the curve is to become a circle, the 3rd point required for this is defined between the above points, i.e. after point 1 and before point 2, move the cursor to point 3 and press and release RControl.
To delete the curve, enter RControl + RButton without moving the cursor.
Code: Select all
>^RButton:: ; CursorOnCurve
IF (OL.5 = "") {
OL:=[] ; OL is needed permanently, everything else only temporarily
Loop, 4 { ; bounding rectangle of all display monitors
SysGet, q,% A_Index + 75
OL[A_Index+5] := q
} OL.8 += OL.6, OL.9 += OL.7
} Else Gosub, OnCurveOff
CoordMode, Mouse, Screen
MouseGetPos, x1, y1
ToolTip,% OL.10:="OnLine: 1. Point recorded"
KeyWait, RButton
MouseGetPos, x2, y2
IF (OL.1:=x1) (OL.2:=y1) <> (OL.3:=x2) (OL.4:=y2) {
OL.0:=OL.12:=True, OL.11 := DllCall("SetWindowsHookEx"
,"Int", 14, "Ptr", RegisterCallback("CursorOnCurve")
,"Ptr", DllCall("GetModuleHandle", "Ptr", 0, "Ptr"), "UInt", 0)
(OL.5:=A_ThisHotkey="RCtrl")?OL.1:=Sqrt((x1-OL.2:=((x1*x1+y1*y1)
*(y2-y3)+(x2*x2+y2*y2)*(y3-y1)+(x3*x3+y3*y3)*(y1-y2))/r0:=2*(x1
*(y2-y3)+x2*(y3-y1)+x3*(y1-y2)))*(x1-OL.2)+(y1-OL.3:=((x1*x1+y1*y1)
*(x3-x2)+(x2*x2+y2*y2)*(x1-x3)+(x3*x3+y3*y3)*(x2-x1))/r0)*(y1-OL.3))
ToolTip,% RegExReplace(OL.10, "\d", 2)
Sleep, 2000
ToolTip,% OL.10:=""
Return
} OnCurveOff:
ToolTip,% OL.0:=OL.10:=OL.12:=""
DllCall("UnhookWindowsHookEx", "Ptr", OL.11)
Return
#IF OL.0 ; if all necessary points are recorded
RCtrl Up::OL.11:=(OL.12:=!OL.12)?DllCall("SetWindowsHookEx"
, "Int", 14, "Ptr", RegisterCallback("CursorOnCurve")
, "Ptr", DllCall("GetModuleHandle", "Ptr", 0, "Ptr"), "UInt", 0)
:DllCall("UnhookWindowsHookEx", "Ptr", OL.11)
#IF OL.10 ; during point recording:
RCtrl:: ; toggles OnLine(2 Points) to OnCircle(3 Points)
#IF
CoordMode, Mouse, Screen
MouseGetPos, x3, y3
ToolTip,% OL.10:="OnCircle: 3. Point recorded"
Return
CursorOnCurve(nCode, wParam, lParam) {
Global OL
If (wParam = 0x0200) { ; WM_MOUSEMOVE
x := NumGet(lParam+0, "Short"), y := NumGet(lParam+4, "Short")
IF OL.5 ; OnCircle OL.1=circle radius, OL.2/OL.3=x/y-center point
x := OL.2+x*r0:=OL.1/Sqrt(x*(x-=OL.2)+y*(y-=OL.3)), y := OL.3+y*r0
Else F := ((w:=OL.3-OL.1)*(x-OL.1)+(h:=OL.4-OL.2)*(y-OL.2))/(w*w+h*h)
,x := Max(OL.6, Min(OL.1+F*w, OL.8)), y := Max(OL.7, Min(OL.2+F*h, OL.9))
Return, !!DllCall("SetCursorPos", "int", x, "int", y)
} Return, DllCall("CallNextHookEx", "UInt", 0, "Int"
, nCode, "UInt", wParam, "UInt", lParam)
}