Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <SendMessage.au3>
#include <Math.au3>
;
Const $margin = 120 ; in px, how far to let stylus move outside the window bounds
Const $minWidth = 600 ; in px, minimum window width (not to require large movements for tiny windows)
Const $minHeight = 300 ; in px, minimum window height (ditto)
Const $pollRate = 5 ; in ms, lower is more likely to notice short taps
;HotKeySet("{pause}", "DoExit") ; keyboard shortcut to exit script, if you need it
; if these ever change, you would find them via AutoIt Window Info:
Const $idY1 = 53
Const $idY2 = 54
Const $idX1 = 55
Const $idX2 = 56
;
Func Clamp($x, $a, $b)
If ($x < $a) Then Return $a
If ($x > $b) Then Return $b
Return $x
EndFunc
;
Func DoExit()
Exit 0
EndFunc
;
Global $desktopX1 = _WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN)
Global $desktopY1 = _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN)
Global $desktopW = _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN)
Global $desktopH = _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)
Global $desktopX2 = $desktopX1 + $desktopW
Global $desktopY2 = $desktopY1 + $desktopH
Global $desktopRect[4] = [$desktopX1, $desktopY1, $desktopW, $desktopH]
;
Global $hwnd = 0x0
Global $hfX1, $hfX2, $hfY1, $hfY2
Func IsMouseDown() ; LMB/RMB/MMB
Return BitAND(_WinAPI_GetAsyncKeyState(0x1), 0x8000) <> 0 _
Or BitAND(_WinAPI_GetAsyncKeyState(0x2), 0x8000) <> 0 _
Or BitAND(_WinAPI_GetAsyncKeyState(0x4), 0x8000) <> 0
EndFunc
;
Func SetRegion_1($h0, $h1, $h2, $v)
_SendMessage($h1, $WM_SETFOCUS, $h0, 0)
ControlSetText($hwnd, "", $h1, String($v))
_SendMessage($h1, $WM_KILLFOCUS, $h2, 0)
EndFunc
Func SetRegion($x1, $y1, $x2, $y2)
Local $h0 = $hwnd
; so, we can't enter x1 that is >x2 and what a trouble
If ($y1 < Int(ControlGetText($hwnd, "", $idY2))) Then
Local $h1 = $hfY1, $v1 = $y1, $h2 = $hfY2, $v2 = $y2
Else
Local $h2 = $hfY1, $v2 = $y1, $h1 = $hfY2, $v1 = $y2
EndIf
If ($x1 < Int(ControlGetText($hwnd, "", $idX2))) Then
Local $h3 = $hfX1, $v3 = $x1, $h4 = $hfX2, $v4 = $x2
Else
Local $h4 = $hfX1, $v4 = $x1, $h3 = $hfX2, $v3 = $x2
EndIf
;
SetRegion_1($h0, $h1, $h2, $v1)
SetRegion_1($h1, $h2, $h3, $v2)
SetRegion_1($h2, $h3, $h4, $v3)
SetRegion_1($h3, $h4, $h2, $v4)
; for some reason we have to do a dance after the last input
_SendMessage($h2, $WM_SETFOCUS, $h4, 0)
_SendMessage($h2, $WM_KILLFOCUS, $h0, 0)
_SendMessage($h0, $WM_SETFOCUS, $h2, 0)
EndFunc
;
Local $curr = 0, $prev = 0
Local $noRect[4] = [0,0,0,0]
Local $cr[4] = [0,0,0,0]
Local $isFullScreen = False
Local $delayUpdate = False
Local $nullPtr = Ptr(0)
Local $noWindowNote = True
While 1
; Config window [re-]opened?
Local $hwnd_ = WinGetHandle("Portion of Screen")
If ($hwnd_ == $nullPtr) Then
If ($noWindowNote) Then
ConsoleWrite("Please open 'Mapping > Screen Area > Portion of Screen' from Wacom Tablet Preferences" & @CRLF)
$noWindowNote = False
EndIf
Sleep($pollRate)
ContinueLoop
EndIf
If ($hwnd <> $hwnd_) Then
$hwnd = $hwnd_
ConsoleWrite("Config window changed to " & $hwnd & @CRLF)
For $attempt = 1 To 50 ; window appears before controls for some reason
Sleep(25)
$hfY1 = ControlGetHandle($hwnd, "", $idY1)
$hfY2 = ControlGetHandle($hwnd, "", $idY2)
$hfX1 = ControlGetHandle($hwnd, "", $idX1)
$hfX2 = ControlGetHandle($hwnd, "", $idX2)
If ($hfY1 <> $nullPtr And $hfY2 <> $nullPtr And _
$hfX1 <> $nullPtr And $hfX2 <> $nullPtr) Then ExitLoop
If ($attempt == 50) Then ConsoleWrite("Couldn't discover controls" & @CRLF)
Next
ConsoleWrite("Controls: "&$hfY1&", "&$hfY2&", "&$hfX1&", "&$hfX2&@CRLF)
EndIf
;
$curr = WinGetHandle("[ACTIVE]")
; Try to walk up the window's parents-chain so that your area doesn't readjust
; simply because you mouseovered a floating panel in Paint.NET:
While ($curr <> 0)
Local $par = _WinAPI_GetWindow($curr, 4) ; GW_OWNER
If ($par <> 0) Then
$curr = $par
Else
ExitLoop
EndIf
WEnd
; figure out whether we need to update
$update = False
If ($curr <> $prev) Then ; active window changed?
$prev = $curr
;$update = True
Local $currClass = _WinAPI_GetClassName($curr)
Local $currTitle = WinGetTitle($curr)
If ($currClass == "Windows.UI.Core.CoreWindow") Then
$isFullScreen = ($currTitle == "Start" Or $currTitle == "Search")
Else
$isFullScreen = False
EndIf
$cr = $noRect
;ConsoleWrite("Class:" & $currClass & @CRLF)
;ConsoleWrite("Title:" & $currTitle & @CRLF)
;ConsoleWrite("Full:" & $isFullScreen & @CRLF)
; same as below:
If (IsMouseDown()) Then $delayUpdate = True
Else
Local $nr = $isFullScreen ? $desktopRect : WinGetPos($curr)
If (Not IsArray($nr)) Then
; we have no permit to even poll the size of this window
ElseIf (IsMouseDown()) Then
; allowing to change target area while mouse is held down causes a variety of side effects
; (such as causing you to drag objects not where you wanted)
$delayUpdate = True
ElseIf IsArray($cr) And ($cr[0]<>$nr[0] Or $cr[1]<>$nr[1] Or $cr[2]<>$nr[2] Or $cr[3]<>$nr[3]) Then
$update = True
$cr = $nr
EndIf
EndIf
;
If ($update And IsArray($cr)) Then
If ($delayUpdate) Then
ConsoleWrite("Wait+")
$delayUpdate = False
Sleep(150)
EndIf
;ConsoleWrite("Update!" & @CRLF)
Local $cx1 = $cr[0]
Local $cy1 = $cr[1]
Local $cw = $cr[2]
Local $ch = $cr[3]
Local $cx2 = $cx1 + $cw
Local $cy2 = $cy1 + $ch
; apply min size:
If ($cw < $minWidth) Then
$cx1 = $cx1 + Floor(($cw - $minWidth) / 2)
$cw = $minWidth
$cx2 = $cx1 + $cw
EndIf
If ($ch < $minHeight) Then
$cy1 = $cy1 + Floor(($ch - $minHeight) / 2)
$ch = $minHeight
$cy2 = $cy1 + $ch
EndIf
; apply margin:
$cx1 = Clamp($cx1 - $margin, $desktopX1, $desktopX2)
$cx2 = Clamp($cx2 + $margin, $desktopX1, $desktopX2)
$cy1 = Clamp($cy1 - $margin, $desktopY1, $desktopY2)
$cy2 = Clamp($cy2 + $margin, $desktopY1, $desktopY2)
; and update:
;ConsoleWrite("SetRegion T"&$cy1&" B"&$cy2&" L"&$cx1&" R"&$cx2&@CRLF)
SetRegion($cx1, $cy1, $cx2, $cy2)
EndIf
;
Sleep($pollRate)
WEnd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.