diff --git a/src/bin/RawInputViewer.au3 b/src/bin/RawInputViewer.au3 index 700afd0..d5a20c3 100644 --- a/src/bin/RawInputViewer.au3 +++ b/src/bin/RawInputViewer.au3 @@ -1,4 +1,164 @@ -#include "include-initialize.au3" +#NoTrayIcon +#include +#include +#Include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mischelper.au3" +#include "hidhelpers.au3" +#include "i18n.au3" +#include "cmdline.au3" +#include "rawhelpers.au3" +#include "winapihelpers.au3" +#include "demo.au3" + +Global Const $GLOBAL_OPTIONS_INI_PATH = "options.ini" +Global Const $GLOBAL_PROGRAM_WINDOW_TITLE = "RawInputViewer" +Global Const $GLOBAL_PROGRAM_ICON_PATH = "%SystemRoot%\System32\joy.cpl" +Global Const $GLOBAL_MAXIMUM_BUFFER_SIZE = 256 +Global Const $GLOBAL_INITIAL_XHAIR_COLOR = 0xff00ff00 +Global Const $GLOBAL_INITIAL_GRIDSIZE = 320 +Global Const $user32dll = DllOpen("user32.dll") +Global Const $kernel32dll = DllOpen('kernel32.dll') +Global Const $PERFORMANCE_FREQUENCY = QueryPerformanceFrequency() + + +If $CMDLINE[0] > 0 then CmdLineHandler($CMDLINE) + + + +If _Singleton( $GLOBAL_PROGRAM_WINDOW_TITLE , 1 ) = 0 Then + WinActivate($GLOBAL_PROGRAM_WINDOW_TITLE) + Exit +Else + opt("GUICloseOnESC",0) + opt("GUIOnEventMode", 1) +; opt("GUIEventOptions", 1) ; manually process min/maximize/resize/store cmds + opt("MustDeclareVars", 1) + opt("WinWaitDelay",0) + opt("SendKeyDelay",0) ; delay between multiple Send commands + opt("SendKeyDownDelay",0) ; duration of each Send keystroke (key hold time) + opt("MouseClickDelay",0) ; delay between multiple mouseclick commands + opt("MouseClickDownDelay",0) ; duration of each mouseclick command (button hold time) + initialize_i18n_strings($GLOBAL_OPTIONS_INI_PATH) +EndIf + +Global $g_framecounter=0, $g_framelabel = "" +Global $g_middle_drag[2], $g_mousetrap_bound[4] +Global $gReportFileMkb, $gReportFileLst + +Global Const $g_msg_subscription_list = [$WM_INPUT, $WM_INPUT_DEVICE_CHANGE, $WM_MOVING, $WM_SIZE, $WM_ENTERMENULOOP, $WM_SYSCOMMAND] +Global Const $g_hForm = GUICreate($i18n_inactive_status & $i18n_program_title_suffix, 430, 600, -1, -1, BitOr($WS_CAPTION,$WS_POPUPWINDOW)) +Global Const $g_toggle_button = GUICtrlCreateButton($i18n_inactive_buttontext, 15, 10, 100, 25) +Global Const $g_suspend_button = GUICtrlCreateButton($i18n_suspend_buttontext, 115, 10, 100, 25) +GUICtrlSetState($g_suspend_button,$GUI_DISABLE) +Global Const $g_device_button = GUICtrlCreateButton($i18n_devices_buttontext, 215, 10, 100, 25) +Global Const $g_demo_button = GUICtrlCreateButton($i18n_demo_buttontext, 315, 10, 100, 25) +Global Const $g_mouse_checkbox = GUICtrlCreateCheckbox($i18n_mouse_checkbox, 15, 35, 100, 35) +GUICtrlSetState($g_mouse_checkbox, $GUI_CHECKED) +Global Const $g_keybd_checkbox = GUICtrlCreateCheckbox($i18n_keyboard_checkbox, 115, 35, 100, 35) +GUICtrlSetState($g_keybd_checkbox, $GUI_CHECKED) +Global Const $g_hidev_checkbox = GUICtrlCreateCheckbox($i18n_hid_checkbox, 215, 35, 200, 35) +Global Const $g_label = GUICtrlCreateEdit($i18n_clicktostart_title & @CRLF, 15, 70, 400, 275, $ES_AUTOVSCROLL + $WS_VSCROLL + $ES_READONLY) +GUICtrlSetFont($g_label, 9, 0, 0, "Consolas") +Global Const $g_log = GUICtrlCreateEdit("== " & $i18n_devicechange_title & " ==" & @CRLF, 15, 360, 400, 230, $ES_AUTOVSCROLL + $WS_VSCROLL + $ES_READONLY) +GUICtrlSetFont($g_log, 9, 0, 0, "Consolas") + +ProgramCommand("init_refresh") +InitializeEventListener() +InitializeGlobalBuffer(true) +RegisterWindowMessagesToCentralHandler($g_msg_subscription_list) ; make sure this is done after initializations so that WM_* messages don't start coming in before the handler buffers are initialized + +GUICtrlSetOnEvent($g_toggle_button, GUICmdScriptToggle) +GUICtrlSetOnEvent($g_suspend_button, GUICmdSuspendButton) +GUICtrlSetOnEvent($g_device_button, GUICmdDeviceButton) +GUICtrlSetOnEvent($g_demo_button, GUICmdDemoButton) +GUISetOnEvent($GUI_EVENT_CLOSE, CmdExitProgram) + +SetProcessDPIAware() +GUISetIcon($GLOBAL_PROGRAM_ICON_PATH) +GUISetState(@SW_SHOW,$g_hForm) +UpdateText("", $g_label) ; inform function of the handle to the editctrl for input message +UpdateList("", null, $g_log) ; inform function of the handle to the editctrl for input device change +Main() + +Func InitBigCursors($hor,$ver) +#cs + Global $hWhiteCursor = _LoadBigCursor(@ScriptDir & "\assets\cursors\white.cur") + Global $hLimeCursor = _LoadBigCursor(@ScriptDir & "\assets\cursors\lime.cur") + Global $hCyanCursor = _LoadBigCursor(@ScriptDir & "\assets\cursors\cyan.cur") + Global $hYellowCursor = _LoadBigCursor(@ScriptDir & "\assets\cursors\yellow.cur") +#ce + Local Static $alreadyRun = False + If $alreadyRun Then Return + $alreadyRun = True + Local $gdi32 = DllOpen('gdi32.dll'),$user32=DllOpen('user32.dll') + Local $hDC = DllCall('user32.dll','handle','GetDC','handle',Null)[0] + Local $rawColor = [ _ + DllStructCreate('dword[' & $hor*$ver & '];') , _ + DllStructCreate('dword[' & $hor*$ver & '];') , _ + DllStructCreate('dword[' & $hor*$ver & '];') , _ + DllStructCreate('dword[' & $hor*$ver & '];') ] + For $i=1 to $ver + For $j=1 to $hor + Local $n = ($i-1)*$hor+$j + If Int($ver/2)+1=$i or Int($hor/2)+1=$j Then + DllStructSetData($rawColor[0], 1, 0xff00ff00, $n) + DllStructSetData($rawColor[1], 1, 0xffffff00, $n) + DllStructSetData($rawColor[2], 1, 0xff00ffff, $n) + DllStructSetData($rawColor[3], 1, 0xffffffff, $n) + EndIf + Next + Next + Local $hbmColor = [ _ + DllCall($gdi32,'handle','CreateBitmap','int',$hor,'int',$ver,'uint',1,'uint',32,'struct*',$rawColor[0])[0] , _ + DllCall($gdi32,'handle','CreateBitmap','int',$hor,'int',$ver,'uint',1,'uint',32,'struct*',$rawColor[1])[0] , _ + DllCall($gdi32,'handle','CreateBitmap','int',$hor,'int',$ver,'uint',1,'uint',32,'struct*',$rawColor[2])[0] , _ + DllCall($gdi32,'handle','CreateBitmap','int',$hor,'int',$ver,'uint',1,'uint',32,'struct*',$rawColor[3])[0] ] + Local $hbmMask = Dllcall($gdi32,'handle','CreateCompatibleBitmap','handle',$hDC, 'int',$hor,'int',$ver)[0] + Local $hCursor = [ _ + CreateIconIndirect(False,int($hor/2),int($ver/2),$hbmMask,$hbmColor[0],$user32) , _ + CreateIconIndirect(False,int($hor/2),int($ver/2),$hbmMask,$hbmColor[1],$user32) , _ + CreateIconIndirect(False,int($hor/2),int($ver/2),$hbmMask,$hbmColor[2],$user32) , _ + CreateIconIndirect(False,int($hor/2),int($ver/2),$hbmMask,$hbmColor[3],$user32) ] + DllCall($gdi32,'bool','DeleteObject','handle',$hbmMask) + DllCall($gdi32,'bool','DeleteObject','handle',$hbmColor[0]) + DllCall($gdi32,'bool','DeleteObject','handle',$hbmColor[1]) + DllCall($gdi32,'bool','DeleteObject','handle',$hbmColor[2]) + DllCall($gdi32,'bool','DeleteObject','handle',$hbmColor[3]) + DllClose($gdi32) + DllClose($user32) + Global $hLimeCursor = $hCursor[0] + Global $hYellowCursor = $hCursor[1] + Global $hCyanCursor = $hCursor[2] + Global $hWhiteCursor = $hCursor[3] + OnAutoItExitRegister(CleanupCursors) +EndFunc + + + + +Func SetProcessDPIAware() + Local $h=GUICreate('') + DllCall("user32.dll", "bool", "SetProcessDPIAware") + GUIDelete($h) +EndFunc + +Func CleanupCursors() + DestroyCursor($hWhiteCursor) + DestroyCursor($hLimeCursor) + DestroyCursor($hCyanCursor) + DestroyCursor($hYellowCursor) +EndFunc Func Main($switch = null) Local Static $state=null @@ -24,7 +184,7 @@ EndFunc Func RegisterWindowMessagesToCentralHandler($arrMsg) for $msg in $arrMsg - GUIRegisterMsg($msg, OnMessage) + GUIRegisterMsg($msg, WndProc) next EndFunc @@ -36,23 +196,24 @@ Func InitializeEventListener() Global $g_eventListenerMaxIndex = 31 Global $g_eventListenerQueued = 0 For $i=0 to $g_eventListenerMaxIndex + $g_eventListenerArgs[$i] = DllStructCreate('hwnd hWnd;uint message;wparam wParam;lparam lParam;dword time;dword pt;lparam info;int64 qpc;') $g_eventListener[$i] = GUICtrlCreateDummy() GUICtrlSetOnEvent($g_eventListener[$i], EventCallbackHandler) Next EndFunc -Func InitializeGlobalBuffer($firstUse=false) - OnMessage(Null, $WM_NULL, Null, Null) ; reset timer in the function +Func InitializeGlobalBuffer($firstUse=false) ; reset timer in the function if not $firstuse then InitializeDummyBuffer($gid_on_wm_input) ; clear dummy buffer if this is not first-time use Global $g_rawinput_maxindex = 63 Global $gid_on_wm_input[$g_rawinput_maxindex+1] -; Global $g_rawinput_misc[$g_rawinput_maxindex+1][3] -; Global $g_rawinput_index[$g_rawinput_maxindex+1] - Global $g_rawinput_buffer[$g_rawinput_maxindex+1][5] + Global $g_rawinput_buffer[$g_rawinput_maxindex+1][3] Global $g_device_list = [] Global $g_rawinput_queued = 0 GUISwitch($g_hForm) InitializeDummyBuffer($gid_on_wm_input,true) + For $i=0 to $g_rawinput_maxindex + $g_rawinput_buffer[$i][2] = DllStructCreate('hwnd hWnd;uint message;wparam wParam;lparam lParam;dword time;dword pt;lparam info;int64 qpc;') + Next EndFunc Func InitializeDummyBuffer(ByRef $array, $flag=false, $func=Callback_WM_INPUT) @@ -70,32 +231,37 @@ Func InitializeDummyBuffer(ByRef $array, $flag=false, $func=Callback_WM_INPUT) EndIf EndFunc -Func OSMessageMetadata($timestampOverride=null) -; Take the Windows-provided timestamp with a grain of salt, as it only has 10-16ms resolution (you just get deltas of 16, 0, 0... etc). -; Run your own QueryPerformanceCounter or equivalents in a consistent, lightweight thread if you need accurate timestamping. - local $msgpos = DllCall($user32dll, 'dword', 'GetMessagePos') - local $ostime = DllCall($user32dll, 'long', 'GetMessageTime') - local $msinfo = DllCall($user32dll, 'lparam', 'GetMessageExtraInfo') - local $array=[ $msgpos[0], $ostime[0], $msinfo[0] ] - if $timestampOverride then $array[1] = $timestampOverride - return $array +Func MakeMessage($h,$m,$w,$l,$q) + Local $_ = DllStructCreate('hwnd hWnd;uint message;wparam wParam;lparam lParam;dword time;dword pt;lparam info;int64 qpc;') + WriteMessage($h,$m,$w,$l,$q,$_) + Return $_ +EndFunc + +Func WriteMessage($h,$m,$w,$l,$q,ByRef $_) + $_.hWnd = $h + $_.message = $m + $_.wParam = $w + $_.lParam = $l + $_.time = DllCall($user32dll, 'long', 'GetMessageTime')[0] + $_.pt = DllCall($user32dll, 'dword', 'GetMessagePos')[0] + $_.info = DllCall($user32dll, 'lparam', 'GetMessageExtraInfo')[0] + $_.qpc = $q EndFunc -Func OnMessage($hWnd, $uMsg, $wParam, $lParam) - local static $epoch=TimerInit(), $buffer_index = 0, $isRecording=false - local $timestamp = TimerDiff($epoch) - Switch $uMsg - Case $WM_INPUT - If $isRecording Then Return ForwardTimestampedRawinput( $hWnd , $uMsg , $wParam , $lParam , OSMessageMetadata( Demo(false) ? $timestamp : null ) ) -; If $isRecording Then Return Debug_Run_Rawinput_Processor_Immediately( $lParam , OSMessageMetadata( Demo(false) ? $timestamp : null ) ) - Case $WM_INPUT_DEVICE_CHANGE - Return ForwardTimestampedMsg(Process_Device_Change, $hWnd, $uMsg, $wParam, $lParam, OSMessageMetadata()) - Case $WM_NULL - $epoch = ( $lParam ? $lParam : TimerInit() ) +Func WndProc($h,$m,$w,$l) + local static $buffer_index = 0, $isRecording=false + local $q = QueryPerformanceCounter($kernel32dll) + Switch $m + Case 0xFF + If $isRecording Then ForwardTimestampedRawinput(MakeMessage($h,$m,$w,$l,$q)) + Return 0 + Case 0xFE + ForwardTimestampedMsg(Process_Device_Change, MakeMessage($h,$m,$w,$l,$q)) + Return 0 Case $WM_NOTIFY - $isRecording = Main($lParam) + $isRecording = Main($l) Case $WM_SYSCOMMAND - If $isRecording then return ($wParam=0xF060 ? $GUI_RUNDEFMSG : 0) ; always return 0 except for the close window message + If $isRecording then return ($w=0xF060 ? $GUI_RUNDEFMSG : 0) ; always return 0 except for the close window message Case $WM_MOVING, $WM_SIZE, $WM_ENTERMENULOOP If $isRecording Then CmdSuspend($g_hForm, true) Case $WM_SETCURSOR @@ -155,166 +321,114 @@ EndFunc ; 0x0002 == XBUTTON2 Triggered by the second X button. ; case of scrollwheel: The high-order word indicates the distance the wheel is rotated, expressed in multiples or divisions of WHEEL_DELTA, which is 120. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. -Func ForwardTimestampedMsg($func, $hWnd, $uMsg, $wParam, $lParam, ByRef $misc) - local $args = DllStructCreate("struct;hwnd hWnd;uint uMsg;wparam wParam;lparam lParam;double time;lparam info;dword pos;endstruct") - DllStructSetData($args, "hWnd", $hWnd) - DllStructSetData($args, "uMsg", $uMsg) - DllStructSetData($args, "wParam", $wParam) - DllStructSetData($args, "lParam", $lParam) - DllStructSetData($args, "pos", $misc[0]) - DllStructSetData($args, "time", $misc[1]) - DllStructSetData($args, "info", $misc[2]) - $g_eventListenerQueued = $g_eventListenerQueued + QueueEvent($func, $args, $misc[1]) - Return 0 +Func ForwardTimestampedMsg($func, $struct) + $g_eventListenerQueued += QueueEvent($func, $struct) EndFunc -Func ForwardTimestampedRawinput($hWnd, $uMsg, $wParam, $lParam, ByRef $misc) - $g_rawinput_queued += WriteToRawinputBuffer($lParam, $misc, $misc[1]) - Return 0 +Func ForwardTimestampedRawinput($struct) + $g_rawinput_queued += WriteToRawinputBuffer($struct) EndFunc Func EventCallbackHandler() local $index = GUICtrlRead(@GUI_CTRLID) local $func = $g_eventListenerFunctions[$index] local $args = $g_eventListenerArgs[$index] -; local $arr[2] = ["CallArgArray", $args] $g_eventListenerStatus[$index] = false $g_eventListenerQueued -= 1 -; Call($func,$arr) $func($args) EndFunc Func Callback_WM_INPUT() local $index = GUICtrlRead(@GUI_CTRLID) - local $data = $g_rawinput_buffer[$index][1] - local $misc = [ $g_rawinput_buffer[$index][2] , $g_rawinput_buffer[$index][3] , $g_rawinput_buffer[$index][4] ] + local $data = $g_rawinput_buffer[$index][1] + local $misc = $g_rawinput_buffer[$index][2] $g_rawinput_buffer[$index][0] = false $g_rawinput_queued -= 1 Process_Rawinput_Data($data, $misc) EndFunc -Func QueueEvent($func, $args, $time) +Func QueueEvent($func, $args) + Local $time = $args.time Local Const $MAX = $GlOBAL_MAXIMUM_BUFFER_SIZE Local Static $buffer_index = 0 If $g_eventListenerQueued < $MAX then - $buffer_index = _Min($buffer_index, $g_eventListenerMaxIndex) - local $i, $j = $buffer_index, $k = $g_eventListenerMaxIndex - For $i = 0 To $k - if $g_eventListenerStatus[$j] then - $j = Mod($j+1, $k+1) - else - $g_eventListenerStatus[$j] = true - $g_eventListenerArgs[$j] = $args - $g_eventListenerFunctions[$j] = $func - GUICtrlSendToDummy($g_eventListener[$j], $j) - $buffer_index = Mod($j+1, $k+1) - Return 1 - endif - Next - Local $a, $b, $c, $d - $a = _ArrayAdd($g_eventListenerStatus, true) - $b = _ArrayAdd($g_eventListenerArgs, $args) - $c = _ArrayAdd($g_eventListenerFunctions, $func) - $d = _ArrayAdd($g_eventListener, GUICtrlCreateDummy()) - GUICtrlSetOnEvent($g_eventListener[$d], "EventCallbackHandler") - GUICtrlSendToDummy($g_eventListener[$d], $b) - $g_eventListenerMaxIndex += 1 - Return ( ( $a = $b ) ? ( 1 ) : ( exit ) ) + $buffer_index = _Min($buffer_index, $g_eventListenerMaxIndex) + local $i, $j = $buffer_index, $k = $g_eventListenerMaxIndex + For $i = 0 To $k + if $g_eventListenerStatus[$j] then + $j = Mod($j+1, $k+1) + else + $g_eventListenerStatus[$j] = true + $g_eventListenerArgs[$j] = $args + $g_eventListenerFunctions[$j] = $func + GUICtrlSendToDummy($g_eventListener[$j], $j) + $buffer_index = Mod($j+1, $k+1) + Return 1 + endif + Next + Local $a, $b, $c, $d + $a = _ArrayAdd($g_eventListenerStatus, true) + $b = _ArrayAdd($g_eventListenerArgs, $args) + $c = _ArrayAdd($g_eventListenerFunctions, $func) + $d = _ArrayAdd($g_eventListener, GUICtrlCreateDummy()) + GUICtrlSetOnEvent($g_eventListener[$d], "EventCallbackHandler") + GUICtrlSendToDummy($g_eventListener[$d], $b) + $g_eventListenerMaxIndex += 1 + Return ( ( $a = $b ) ? ( 1 ) : ( exit ) ) Else - FileWrite($gReportFileMkb, "DROPPED EVENT " & $func & " AT T=" & $time & @CRLF) - Return 0 + FileWrite($gReportFileMkb, "DROPPED EVENT " & $func & " AT T=" & $time & @CRLF) + Return 0 EndIf EndFunc -Func WriteToRawinputBuffer($lParam, ByRef $misc, $time) - Local Static $tHeader = 'struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;' - Local Static $tMouse = $tHeader & 'ushort Flags;ushort Alignment;ushort ButtonFlags;short ButtonData;ulong RawButtons;long LastX;long LastY;ulong ExtraInformation;' , _ - $tKeybd = $tHeader & 'ushort MakeCode;ushort Flags;ushort Reserved;ushort VKey;uint Message;ulong ExtraInformation;' , _ - $tHidev = $tHeader & 'dword SizeHid;dword Count;' - Local Static $sizeHeader = DllStructGetSize(DllStructCreate($tHeader)), _ - $sizeMouse = DllStructGetSize(DllStructCreate($tMouse)), _ - $sizeKeybd = DllStructGetSize(DllStructCreate($tKeybd)), _ - $sizeHIDev = DllStructGetSize(DllStructCreate($tHidev)) +Func WriteToRawinputBuffer($misc) Local Static $buffer_index = 0 - Local $a = DllCall($user32dll, _ - 'uint', 'GetRawInputData', _ - 'handle', $lParam, _ - 'uint', 0x10000005, _ - 'struct*', DllStructCreate($tHeader), _ - 'uint*', $sizeHeader, _ - 'uint', $sizeHeader) - - If $a[0] Then - Switch DllStructGetData($a[3],"Type") - Case 0 ; mouse - Local $tag = $tMouse - Case 1 ; keyboard - Local $tag = $tKeybd - Case 2 ; hid - Local $tag = $tHidev & 'byte RawData[' & (DllStructGetData($a[3],"Size")-$sizeHidev) & '];' - Case Else - FileWrite($gReportFileMkb, "INVALID TYPE AT T=" & $time & @CRLF) - Return 0 - EndSwitch - ; if this is changed to getrawinputbuffer then it would simply loop through them and increment a counter for number of reports added, then return that counter. - ; Race condition check is done each time a report is added - $a = DllCall($user32dll, _ - 'uint', 'GetRawInputData', _ - 'handle', $lParam, _ - 'uint', 0x10000003, _ - 'struct*', DllStructCreate($tag), _ - 'uint*', DllStructGetData($a[3],"Size"), _ - 'uint', $sizeHeader) - if $a[0] then - $buffer_index = _Min($buffer_index, $g_rawinput_maxindex) - local $i, $j = $buffer_index, $k = $g_rawinput_maxindex - if $g_rawinput_queued<$GLOBAL_MAXIMUM_BUFFER_SIZE then ; if the number of queued events isn't full, scan buffer to check that it's not already occupied - For $i = 0 To $k ; loop through the buffer once, submit and return if found an empty slot - if $g_rawinput_buffer[$j][0] then - $j = Mod($j+1, $k+1) - else - $g_rawinput_buffer[$j][0] = true - $g_rawinput_buffer[$j][1] = $a[3] - $g_rawinput_buffer[$j][2] = $misc[0] ; position - $g_rawinput_buffer[$j][3] = $misc[1] ; timestamp - $g_rawinput_buffer[$j][4] = $misc[2] ; extrainfo - GUICtrlSendToDummy($gid_on_wm_input[$j], $j) - $buffer_index = Mod($j+1, $k+1) - Return 1 ; returns number of reports advanced to the buffer, which is 1 - endif - Next - Return ExpandDummyBuffer($a[3], $misc) ; if no empty slot is found after one loop, expand the buffer by 1, and report that 1 message has been added - else ; if buffer cannot be expanded further, simply look for any stale report to overwrite, and report that one has been overwritten - For $i = 0 To $k - if $g_rawinput_buffer[$j][3]>=$time then ; if report is fresher than current, don't overwrite - $j = Mod($j+1, $k+1) - else - $g_rawinput_buffer[$j][0] = true - $g_rawinput_buffer[$j][1] = $a[3] - $g_rawinput_buffer[$j][2] = $misc[0] ; position - $g_rawinput_buffer[$j][3] = $misc[1] ; timestamp - $g_rawinput_buffer[$j][4] = $misc[2] ; extrainfo - GUICtrlSendToDummy($gid_on_wm_input[$j], $j) - $buffer_index = Mod($j+1, $k+1) - Return 1 ; even though it's overwritten, the previously written but stale event is still already queued, so eventually it will clear its own count, thus us adding one new event will invariably increase the number of events queued to the Autoit engine - endif - Next - FileWrite($gReportFileMkb, "DROPPED INPUT AT T=" & $time & @CRLF) - Return 0 - endif - else - FileWrite($gReportFileMkb, "NO CONTENT AT T=" & $time & @CRLF) - Return 0 - endif - Else - FileWrite($gReportFileMkb, "NO HEADER AT T=" & $time & @CRLF) - Return 0 + Local $inputsWritten, $data = _RawInputFetchData($misc.lParam, $user32dll) + If Not IsDllStruct($data) Then + FileWrite($gReportFileMkb, "FAILED FETCH AT T=" & $misc.time & @CRLF) + $inputsWritten = 0 + Return $inputsWritten EndIf + $buffer_index = _Min($buffer_index, $g_rawinput_maxindex) + local $i, $j = $buffer_index, $k = $g_rawinput_maxindex + if $g_rawinput_queued<$GLOBAL_MAXIMUM_BUFFER_SIZE then ; if the number of queued events isn't full, scan buffer to check that it's not already occupied + For $i = 0 To $k ; loop through the buffer once, submit and return if found an empty slot + if $g_rawinput_buffer[$j][0] then + $j = Mod($j+1, $k+1) + else + $g_rawinput_buffer[$j][0] = true + $g_rawinput_buffer[$j][1] = $data + $g_rawinput_buffer[$j][2] = $misc + GUICtrlSendToDummy($gid_on_wm_input[$j], $j) + $buffer_index = Mod($j+1, $k+1) + $inputsWritten = 1 + Return $inputsWritten + endif + Next + Return ExpandDummyBuffer($data, $misc) ; if no empty slot is found after one loop, expand the buffer by 1, and report that 1 message has been added + else ; if buffer cannot be expanded further, simply look for any stale report to overwrite, and report that one has been overwritten + For $i = 0 To $k + if ($g_rawinput_buffer[$j][2]).time>=$misc.time then ; if report is fresher than current, don't overwrite + $j = Mod($j+1, $k+1) + else + $g_rawinput_buffer[$j][0] = true + $g_rawinput_buffer[$j][1] = $data + $g_rawinput_buffer[$j][2] = $misc + GUICtrlSendToDummy($gid_on_wm_input[$j], $j) + $buffer_index = Mod($j+1, $k+1) + $inputsWritten = 1 ; even though it's overwritten, the previously written but stale event is still already queued, so eventually it will clear its own count, thus us adding one new event will invariably increase the number of events queued to the Autoit engine + Return $inputsWritten + endif + Next + FileWrite($gReportFileMkb, "DROPPED INPUT AT T=" & $misc.time & @CRLF) + endif + $inputsWritten = 0 + Return $inputsWritten EndFunc -Func ExpandDummyBuffer($tRIM, ByRef $misc) +Func ExpandDummyBuffer($tRIM, $misc) Local $oldmaxindex = $g_rawinput_maxindex - ReDim $g_rawinput_buffer[$oldmaxindex+2][5] + ReDim $g_rawinput_buffer[$oldmaxindex+2][3] $g_rawinput_buffer[$oldmaxindex+1][0] = true $g_rawinput_maxindex += 1 if $oldmaxindex+1 = $g_rawinput_maxindex then @@ -322,9 +436,7 @@ Func ExpandDummyBuffer($tRIM, ByRef $misc) Local $dummyindex = _ArrayAdd($gid_on_wm_input, GUICtrlCreateDummy()) GUICtrlSetOnEvent( $gid_on_wm_input[$dummyindex], "Callback_WM_INPUT") $g_rawinput_buffer[$oldmaxindex+1][1] = $tRIM - $g_rawinput_buffer[$oldmaxindex+1][2] = $misc[0] - $g_rawinput_buffer[$oldmaxindex+1][3] = $misc[1] - $g_rawinput_buffer[$oldmaxindex+1][4] = $misc[2] + $g_rawinput_buffer[$oldmaxindex+1][2] = $misc GUICtrlSendToDummy($gid_on_wm_input[$dummyindex], $oldmaxindex+1) return 1 else @@ -333,50 +445,19 @@ Func ExpandDummyBuffer($tRIM, ByRef $misc) endif EndFunc -Func Debug_Run_Rawinput_Processor_Immediately($lParam, ByRef $misc) - Local $tRIM = DllStructCreate($tagRAWINPUTHEADER) - If _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_HEADER) then - Switch DllStructGetData($tRIM,"Type") - Case 0 ; mouse - $tRIM = DllStructCreate($tagRAWINPUTMOUSE) - Case 1 ; keyboard - $tRIM = DllStructCreate($tagRAWINPUTKEYBOARD) - Case 2 ; hid - $tRIM = DllStructCreate($tagRAWINPUTHID) - EndSwitch - if _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) then - Process_Rawinput_Data($tRIM, $misc) - else - FileWrite($gReportFileMkb, "NODATA AT T=" & $misc[1] & @CRLF) - endif - EndIf - Return 0 -EndFunc - Func RawinputStateController($enable=null) - ; UsagePage 0x01 = generic desktop controls; Usage 0x01 = pointer - ; UsagePage 0x01 = generic desktop controls; Usage 0x02 = mouse - ; UsagePage 0x01 = generic desktop controls; Usage 0x03 = reserved - ; UsagePage 0x01 = generic desktop controls; Usage 0x04 = joystick - ; UsagePage 0x01 = generic desktop controls; Usage 0x05 = gamepad - ; UsagePage 0x01 = generic desktop controls; Usage 0x06 = keyboard Local Const $defaultregistry = [[]] Local Static $registeredusages=$defaultregistry - Local $flags, $handle Switch $enable Case True - $flags = $RIDEV_INPUTSINK+$RIDEV_DEVNOTIFY - $handle = $g_hForm InitializeGlobalBuffer() $registeredusages = GetConnectedRawinputDevicesUsages(GetDeviceSubscriptionMode()) For $i=0 to UBound($registeredusages,1)-1 - RegisterRawInputDevice($registeredusages[$i][0], $registeredusages[$i][1], $flags, $handle) + _RawInputRegisterDevice($registeredusages[$i][0], $registeredusages[$i][1], 0x00002100, $g_hForm) Next Case False - $flags = $RIDEV_REMOVE - $handle = "" For $i=0 to UBound($registeredusages,1)-1 - RegisterRawInputDevice($registeredusages[$i][0], $registeredusages[$i][1], $flags, $handle) + _RawInputRegisterDevice($registeredusages[$i][0], $registeredusages[$i][1], 0x00000001, Null) Next $registeredusages=$defaultregistry Case Else @@ -384,201 +465,54 @@ Func RawinputStateController($enable=null) EndSwitch EndFunc - - -; https://www.freebsddiary.org/APC/usb_hid_usages.php -; Usage ID Usage Name hidusage.h constant -; 0x00 Undefined -; 0x01 Pointer HID_USAGE_GENERIC_POINTER -; 0x02 Mouse HID_USAGE_GENERIC_MOUSE -; 0x03 Reserved -; 0x04 Joystick HID_USAGE_GENERIC_JOYSTICK -; 0x05 Game Pad HID_USAGE_GENERIC_GAMEPAD -; 0x06 Keyboard HID_USAGE_GENERIC_KEYBOARD -; 0x07 Keypad HID_USAGE_GENERIC_KEYPAD -; 0x08 Multi-axis Controller HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER -; -; NOTE: each process gets only one subscription to the same device class. -; Registering multiple windows to the same device class just makes the OS send their messages only to latest one that signed up - - - -Func RegisterRawInputDevice($usagepage, $usage, $flags, $htarget) - Local $tRID = DllStructCreate($tagRAWINPUTDEVICE) - DllStructSetData($tRID, 'UsagePage', $usagepage) - DllStructSetData($tRID, 'Usage', $usage) - DllStructSetData($tRID, 'Flags', $flags) - DllStructSetData($tRID, 'hTarget', $htarget) - _WinAPI_RegisterRawInputDevices($tRID) -EndFunc - Func Process_Device_Change($msg) - GUIRegisterMsg( $WM_INPUT, '' ) ; halt inflow of rawinput messages without changing system state -; Local $hWnd = DllStructGetData($msg,"hWnd") -; Local $uMsg = DllStructGetData($msg,"uMsg") - Local $wParam = DllStructGetData($msg,"wParam") - Local $lParam = DllStructGetData($msg,"lParam") - Local $pos = DllStructGetData($msg,"pos") - Local $time = DllStructGetData($msg,"time") - Local $info = DllStructGetData($msg,"info") - - Local $posX = BitAnd($pos, 0xFFFF) - Local $posY = BitShift($pos, 16) - Local $str_info = "0x" & Hex($info, 16) - - - Local $add = ($wParam-1) ? (false) : (true) - Local $filelog, $logstring = ( ($add) ? ("+") : ("-") ) & Hex($lParam) & " (t=" & $time & ", x=" & $posX & ", y=" & $posY & ")" & @CRLF + GUIRegisterMsg( 0xFF, '' ) ; halt inflow of rawinput messages without changing system state + Local $p = DllStructCreate('short x;short y',DllStructGetPtr($msg,'pt')) + Local $add = ($msg.wParam-1) ? (false) : (true) + Local $filelog, $logstring = ( ($add) ? ("+") : ("-") ) & Hex($msg.lParam) & " (t=" & $msg.time & ", x=" & $p.x & ", y=" & $p.y & ")" & @CRLF UpdateList($logstring) + FileWrite($gReportFileMkb, MakeLogString(Null,$msg)) If $add Then - FileWrite($gReportFileMkb, "arrve=,0x" & Hex($lParam,16) & ", =,, =,, =,, =,, =,, ostime=," & $time & ", oscoord=,(" & $posX & " " & $posY & "), osextra=" & $str_info & @CRLF) - FileWrite($gReportFileLst, @CRLF & "==============" & @CRLF & " GIDC_ARRIVAL " & @CRLF & "==============" & @CRLF & GetConnectedRawinputDevicesInfoString($lParam) & @CRLF) + FileWrite($gReportFileLst, @CRLF & "==============" & @CRLF & " GIDC_ARRIVAL " & @CRLF & "==============" & @CRLF & GetConnectedRawinputDevicesInfoString($msg.lParam) & @CRLF) Else - FileWrite($gReportFileMkb, "remov=,0x" & Hex($lParam,16) & ", =,, =,, =,, =,, =,, ostime=," & $time & ", oscoord=,(" & $posX & " " & $posY & "), osextra=" & $str_info & @CRLF) - FileWrite($gReportFileLst, @CRLF & "==============" & @CRLF & " GIDC_REMOVAL " & @CRLF & "==============" & @CRLF & "Handle: 0x" & Hex($lParam,16) & @CRLF) + FileWrite($gReportFileLst, @CRLF & "==============" & @CRLF & " GIDC_REMOVAL " & @CRLF & "==============" & @CRLF & "Handle: 0x" & Hex($msg.lParam,16) & @CRLF) EndIf - GUIRegisterMsg( $WM_INPUT, OnMessage ) ; restore inflow of rawinput messages -EndFunc - - -Func Process_Rawinput_Data($tRIM, ByRef $misc) - Local Static $lastMouTime, $lastKeyTime, $lastHidTime ; TODO: keep track of per-device delta time rather than lumping by type - Local $cacheMouTime=$lastMouTime - Local $cacheKeyTime=$lastKeyTime - Local $cacheHidTime=$lastHidTime - Local $posX = BitAnd($misc[0], 0xFFFF) ; from GetMessagePos(), lo-short - Local $posY = BitShift($misc[0], 16) ; from GetMessagePos(), hi-short - Local $time = $misc[1] ; from GetMessageTime() - Local $info = "0x"&Hex($misc[2], 16) ; from GetMessageExtraInfo() - - ; RAWINPUTHEADER - Local $dwType = DllStructGetData($tRIM, 'Type') ; RIM_TYPEMOUSE 0, RIM_TYPEKEYBOARD 1, RIM_TYPEHID 2 - Local $dwSize = DllStructGetData($tRIM, 'Size') ; The size, in bytes, of the entire input packet of data. This includes RAWINPUT plus possible extra input reports in the RAWHID variable length array. - Local $hDevice = DllStructGetData($tRIM, 'hDevice') - Local $wParam = DllStructGetData($tRIM, 'wParam') - - Switch $dwType - Case 0 ; RAWMOUSE - - Local $deltaTime = $cacheMouTime > $time ? $cacheMouTime : $time - $cacheMouTime - $lastMouTime = $time - - Local $usFlags = DllStructGetData($tRIM, 'Flags') ; Specifies a bitwise OR of one or more of the mouse indicator flags. - Local $usButtonFlags = DllStructGetData($tRIM, 'ButtonFlags') ; Specifies the transition state of the mouse buttons. - Local $usButtonData = DllStructGetData($tRIM, 'ButtonData') ; Specifies mouse wheel data, if MOUSE_WHEEL is set in ButtonFlags. - Local $ulRawButtons = DllStructGetData($tRIM, 'RawButtons') ; Specifies the raw state of the mouse buttons. The Win32 subsystem does not use this member. - Local $lLastX = DllStructGetData($tRIM, 'LastX') ; Specifies the signed relative or absolute motion in the x direction. - Local $lLastY = DllStructGetData($tRIM, 'LastY') ; Specifies the signed relative or absolute motion in the y direction. - Local $ulExtraInfo = DllStructGetData($tRIM, 'ExtraInformation') ; Specifies device-specific information. - - ; put whatever extra function you want to do here. This is where you would filter inputs by device and process them separately - if Demo(false) then - local static $alttabbed=false - if $wParam then ; as soon as one in-background report is received, we know we are alt-tabbed - $alttabbed = true ; keep setting it to true, even as you receive them - else ; window restore check - if $alttabbed then ; if was alttabbed but now are receiving foreground, then we are no longer alttabbed - $alttabbed = false ; no longer alttabbed - CameraLockSetState() ; re-lock cursor accordingly + GUIRegisterMsg( 0xFF, WndProc) ; restore inflow of rawinput messages +EndFunc + + +Func Process_Rawinput_Data($raw, $misc) + Local $_ = RAWINPUT($raw) + Local $t = $misc.time + Local Static $p = DllStructCreate('short x;short y') + Local Static $write = DllStructCreate('dword;',DllStructGetPtr($p)) + DllStructSetData($write,1,$misc.pt) + If Demo(false) Then + Switch $_.Type + Case 0 + local static $alttabbed=false + if $_.wParam then ; as soon as one in-background report is received, we know we are alt-tabbed + $alttabbed = true ; keep setting it to true, even as you receive them + else ; window restore check + if $alttabbed then ; if was alttabbed but now are receiving foreground, then we are no longer alttabbed + $alttabbed = false ; no longer alttabbed + CameraLockSetState() ; re-lock cursor accordingly + UpdateButtonState(2,0,0,0) + endif + if (not $_.Flags) and ($_.LastX or $_.LastY) then UpdateMovementCmd($_.LastX, $_.LastY, $p.x, $p.y, $_.hDevice) ; It is ok to move first before updating buttons, since you can't distinguish between the order witin the same report. + if $_.ButtonFlags then UpdateButtonState($_.ButtonFlags, $_.ButtonData, $p.x, $p.y, $_.hDevice) endif - if $lLastX or $lLastY then UpdateMovementCmd($lLastX, $lLastY, $posX, $posY, $hDevice) ; It is ok to move first before updating buttons, since you can't distinguish between the order witin the same report. - if $usButtonFlags then UpdateButtonState($usButtonFlags, $usButtonData, $hDevice) - endif - FileWrite($gReportFileMkb, "mouse=," & $hDevice & ", bflg=,0x" & Hex($usButtonFlags,4) & ", bdta=,0x" & Hex($usButtonData,2) & ", dx=," & $lLastX & ", dy=," & $lLastY & ", dt=," & $deltaTime & ", time=," & $time & ", oscoord=,(" & $posX & " " & $posY & ")" & @CRLF) - else - local $newstring = "== RAWINPUTHEADER ==" & @CRLF & _ - "Device Type: " & _deviceType($dwType) & @CRLF & _ - "Report Size: " & $dwSize & " bytes" & @CRLF & _ - "Device Handle: " & $hDevice & @CRLF & _ - "Received in Background: " & ($wParam?"TRUE":"FALSE") & @CRLF & _ - @CRLF & _ - "== RAWMOUSE ==" & @CRLF & _ - "Delta: " & $lLastX & ", " & $lLastY & @CRLF & _ - "Flags: " & "0x" & Hex($usFlags,4) & _usFlagsMouse($usFlags) & @CRLF & _ - "Button Flag: " & "0x" & Hex($usButtonFlags,4) & _usButtonFlags($usButtonFlags) & @CRLF & _ - "Button Data: " & ($usButtonData>0?"+"&$usButtonData:$usButtonData) & @CRLF & _ - "Raw Buttons: " & "0x" & Hex($ulRawButtons,16) & @CRLF & _ - "Extra Info: " & "0x" & Hex($ulExtraInfo,16) & @CRLF & _ - @CRLF & _ - "== MSGINFO ==" & @CRLF & _ - "OS Timestamp: " & $time & " ms" & @CRLF & _ - "OS EvntCoord: " & $posX & ", " & $posY & @CRLF & _ - "OS ExtraInfo: " & $info ;& ", " & $deltaTime - UpdateText($newstring) ; this only writes to static variable in the function without triggering update - FileWrite($gReportFileMkb, "mouse=," & $hDevice & ", bflg=,0x" & Hex($usButtonFlags,4) & ", bdta=,0x" & Hex($usButtonData,2) & ", dx=," & $lLastX & ", dy=," & $lLastY & ", ostime=," & $time & ", oscoord=,(" & $posX & " " & $posY & ")" & @CRLF) - endif - - - Case 1 ; RAWKEYBOARD - - Local $deltaTime = $cacheKeyTime > $time ? $cacheKeyTime : $time - $cacheKeyTime - $lastKeyTime = $time - - Local $usMakeCode = DllStructGetData($tRIM, 'MakeCode') ; Specifies the scan code (from Scan Code Set 1) associated with a key press. - Local $usFlags = DllStructGetData($tRIM, 'Flags') ; Flags for scan code information. It can be one or more of the following: 0, 1, 2, 4 for keydown, keyup, E0 prefix, E1 prefix - Local $usReserved = DllStructGetData($tRIM, 'Reserved') ; Reserved; must be zero. - Local $usVkey = DllStructGetData($tRIM, 'Vkey') ; The corresponding legacy virtual-key code. - Local $uiMessage = DllStructGetData($tRIM, 'Message') ; The corresponding legacy keyboard window message, for example WM_KEYDOWN, WM_SYSKEYDOWN, and so forth. - Local $ulExtraInfo = DllStructGetData($tRIM, 'ExtraInformation') ; The device-specific additional information for the event. - - if Demo(false) then - if not $wParam then - if $usVkey = 0x1b then GUICmdDemoButton() - endif - FileWrite($gReportFileMkb, "keybd=," & $hDevice & ", wmsg=,0x" & Hex($uiMessage,4) & ", vkey=,0x" & Hex($usVkey,2) & ", make=," & Hex($usMakeCode,2) & ", flag=," & $usFlags & ", dt=," & $deltaTime & ", time=," & $time & @CRLF) - else - local $newstring = "== RAWINPUTHEADER ==" & @CRLF & _ - "Device Type: " & _deviceType($dwType) & @CRLF & _ - "Report Size: " & $dwSize & " bytes" & @CRLF & _ - "Device Handle: " & $hDevice & @CRLF & _ - "Received in Background: " & ($wParam?"TRUE":"FALSE") & @CRLF & _ - @CRLF & _ - "== RAWKEYBOARD ==" & @CRLF & _ - "Make Code: " & "0x" & Hex($usMakeCode,4) & @CRLF & _ - "Flags: " & "0x" & Hex($usFlags,4) & _usFlagsKeyboard($usFlags) & @CRLF & _ - "Reserved: " & "0x" & Hex($usReserved,4) & @CRLF & _ - "Virtual Key: " & "0x" & Hex($usVkey,4) & _usVkey($usVkey) & @CRLF & _ - "Win Message: " & "0x" & Hex($uiMessage,8) & _uiMessage($uiMessage) & @CRLF & _ - "Extra Info: " & "0x" & Hex($ulExtraInfo,16) & @CRLF & _ - @CRLF & _ - "== MSGINFO ==" & @CRLF & _ - "OS Timestamp: " & $time & " ms" & @CRLF & _ - "OS EvntCoord: " & $posX & ", " & $posY & @CRLF & _ - "OS ExtraInfo: " & $info ;& ", " & $deltaTime - UpdateText($newstring) ; this only writes to static variable in the function without triggering update - FileWrite($gReportFileMkb, "keybd=," & $hDevice & ", wmsg=,0x" & Hex($uiMessage,4) & ", vkey=,0x" & Hex($usVkey,2) & ", make=," & Hex($usMakeCode,2) & ", flag=," & $usFlags & ", ostime=," & $time & ", oscoord=,(" & $posX & " " & $posY & ")" & @CRLF) - endif - - Case 2 ; RAWHID - Local $deltaTime = $cacheHidTime > $time ? $cacheHidTime : $time - $cacheHidTime - $lastHidTime = $time - - Local $dwSizeHid = DllStructGetData($tRIM, 'SizeHid') - Local $dwCount = DllStructGetData($tRIM, 'Count') - Local $bRawData = DllStructGetData($tRIM, 'RawData') - if Demo(false) then - else - local $newstring = "== RAWINPUTHEADER ==" & @CRLF & _ - "Device Type: " & _deviceType($dwType) & @CRLF & _ - "Report Size: " & $dwSize & " bytes" & @CRLF & _ - "Device Handle: " & $hDevice & @CRLF & _ - "Received in Background: " & ($wParam?"TRUE":"FALSE") & @CRLF & _ - @CRLF & _ - "== RAWHID ==" & @CRLF & _ - "Bytes per Input: " & $dwSizeHid & @CRLF & _ - "Number of Inputs: " & $dwCount & @CRLF & _ - "Raw Data: " & $bRawData & @CRLF & _ - @CRLF & _ - "== MSGINFO ==" & @CRLF & _ - "OS Timestamp: " & $time & " ms" & @CRLF & _ - "OS EvntCoord: " & $posX & ", " & $posY & @CRLF & _ - "OS ExtraInfo: " & $info ;& ", " & $deltaTime - UpdateText($newstring) ; this only writes to static variable in the function without triggering update - endif - - FileWrite($gReportFileMkb, "hidev=," & $hDevice & ", byte=," & $dwSizeHid & ", ninp=," & $dwCount & ", rdta=," & $bRawData & ", =,, ostime=," & $time & ", oscoord=,(" & $posX & " " & $posY & ")" & @CRLF) + Case 1 + if not $_.wParam then + if $_.VKey = 0x1b then GUICmdDemoButton() + endif + Case 2 + EndSwitch + Else + UpdateText(MakeReportString($raw,$misc)) ; this only writes to static variable in the function without triggering update + EndIf + FileWrite($gReportFileMkb,MakeLogString($raw,$misc)) - EndSwitch EndFunc Func UpdateText($newstring="", $newhandle=null) @@ -606,330 +540,6 @@ Func UpdateList($newstring="", $overwrite=null, $newhandle=null) if $newstring then GUICtrlSetData($handle, $newstring, "append") if $overwrite then GUICtrlSetData($handle, $newstring) EndFunc - -Func UpdateMovementCmd($lLastX, $lLastY, $posX, $posY, $handle=null) - Local Static $singleton_cache = DemoSingletonState() ; TODO: refactor DemoSingletonState to take device handle and return struct address, then change this line to Local instead of Local Static (and pass handle) - Local $cameramode = DllStructGetData($singleton_cache, "camlock") - Local $drag_state = DllStructGetData($singleton_cache, "draglock") - Local $sendX=0, $sendY=0 - if $cameramode then ; camlock mode true, FPS-like - $sendX = $lLastX - $sendY = $lLastY - else ; camlock mode false, RTS-like - if $drag_state then - ; drag pan - $sendX = -$lLastX - $sendY = -$lLastY - else - ; edge pan - if ($posX+$lLastX<$g_mousetrap_bound[0]) or ($posX+$lLastX>$g_mousetrap_bound[2]-1) then $sendX=$lLastX - if ($posY+$lLastY<$g_mousetrap_bound[1]) or ($posY+$lLastY>$g_mousetrap_bound[3]-1) then $sendY=$lLastY - endif - endif - MoveMouseDelta($sendX, $sendY, $singleton_cache) -EndFunc - -Func UpdateButtonState($usButtonFlags, $usButtonData, $handle=null) - Local Static $singleton_cache = DemoSingletonState() ; TODO: refactor DemoSingletonState to take device handle and return struct address, then change this line to Local instead of Local Static (and pass handle) - Local $xhairstate = DllStructGetData($singleton_cache, "color") - Local $cameramode = DllStructGetData($singleton_cache, "camlock") - Local $drag_state = DllStructGetData($singleton_cache, "draglock") - - ; crosshair color state. Is latency sensitive - if BitAND($usButtonFlags,1) then $xhairstate = BitOR( $xhairstate, 0x000000ff ) ; add blue to state - if BitAND($usButtonFlags,2) then $xhairstate = BitAND($xhairstate, 0xffffff00 ) ; subtract blue from state - if BitAND($usButtonFlags,4) then $xhairstate = $cameramode ? BitAND($xhairstate, 0x00ff00ff ) : BitOR( $xhairstate, 0xff00ff00 ) - if BitAND($usButtonFlags,16) then $xhairstate = BitOR( $xhairstate, 0x00ff0000 ) ; add red to state - if BitAND($usButtonFlags,32) then $xhairstate = BitAND($xhairstate, 0xff00ffff ) ; subtract red from state - if $usButtonFlags then - SetCrosshairColor($xhairstate, $singleton_cache) ; only update color if actual commands are sent - Switch BitAND(0x00ffffff,$xhairstate) - Case 0x00ffffff - DllCall($user32dll, "handle", "SetCursor", "handle", $hWhiteCursor[0]) - Case 0x0000ffff - DllCall($user32dll, "handle", "SetCursor", "handle", $hCyanCursor[0]) - Case 0x00ffff00 - DllCall($user32dll, "handle", "SetCursor", "handle", $hYellowCursor[0]) - Case 0x0000ff00 - DllCall($user32dll, "handle", "SetCursor", "handle", $hLimeCursor[0]) - EndSwitch - endif - - ; camera mode toggle check. Not latency-sensitive - if BitAND($usButtonFlags,1) then DragLockSetState(true, $singleton_cache) - if BitAND($usButtonFlags,2+16) then DragLockSetState(false, $singleton_cache) - if BitAND($usButtonFlags,4) then CameraLockSetState(not $cameramode, $singleton_cache) - if BitAND($usButtonFlags,1024) then ChangeZoomLevel($usButtonData, $singleton_cache) - - ; TODO: these should be per device - if BitAND(BitAND($usButtonFlags,16),16) then - $g_middle_drag = MouseGetPos() - AdlibRegister ( "PanCamera" , 10 ) - endif - if BitAND($usButtonFlags,1+4+32) then - AdlibUnRegister ( "PanCamera" ) - endif -EndFunc - -Func CameraLockSetState($lock=null, $ptr=null) - Local Static $singleton_cache=DemoSingletonState() ; TODO: refactor DemoSingletonState to take device handle and return struct address, then change this line to Local instead of Local Static (and pass handle) - Local $address = ($ptr=null) ? $singleton_cache : $ptr - if $lock=null then - Demo(false, DllStructGetData($address,"camlock")) ; default case just locks all devices accordingly, although the per-device feature is currently a stub - else - DllStructSetData($address, "camlock", $lock) - Demo(false, $lock) - endif - ; TODO: bad idea to call a higher level function like Demo() from a low level one like this -EndFunc - -Func DragLockSetState($lock, $ptr) - DllStructSetData($ptr, "draglock", $lock) -EndFunc - -Func MoveMouseDelta($dx, $dy, $ptr) - DllStructSetData($ptr, "x", DllStructGetData($ptr, "x")+$dx) - DllStructSetData($ptr, "y", DllStructGetData($ptr, "y")+$dy) -EndFunc - -Func SetCrosshairColor($color, $ptr) - DllStructSetData($ptr, "color", $color) -EndFunc - -Func ChangeZoomLevel($step, $ptr) - Local Const $scale = 2 - Local Const $period = 12*120 - Local $newmodx, $newmody, $newmodz, $newsize, $magnify - Local $oldmodx = DllStructGetData($ptr,"x") - Local $oldmody = DllStructGetData($ptr,"y") - Local $oldmodz = DllStructGetData($ptr,"z") - Local $oldsize = DllStructGetData($ptr,"gridsize") - $newmodz = $oldmodz + $step - $newmodz = $newmodz - $period*round($newmodz/$period) - $newsize = round( $GLOBAL_INITIAL_GRIDSIZE*exp(log($scale)*$newmodz/$period) ) - $magnify = exp(log($scale)*($step)/$period) - if $newmodz-$oldmodz < $step then - $newmody = round(mod($oldmody+$oldsize/$scale,$oldsize)*$magnify) - $newmodx = round(mod($oldmodx+$oldsize/$scale,$oldsize)*$magnify) - elseif $newmodz-$oldmodz > $step then - $newmody = round(mod($oldmody*$magnify-$newsize/$scale,$newsize)) - $newmodx = round(mod($oldmodx*$magnify-$newsize/$scale,$newsize)) - else ; if not wrapped - $newmody = round(mod($oldmody,$oldsize)*$magnify) - $newmodx = round(mod($oldmodx,$oldsize)*$magnify) - endif - DllStructSetData( $ptr, "x", $newmodx ) ; renormalize - DllStructSetData( $ptr, "y", $newmody ) ; renormalize - DllStructSetData( $ptr, "z", $newmodz ) - DllStructSetData( $ptr, "gridsize", $newsize ) -EndFunc - -Func InitializeSingletonState() - Local Static $singleton_demo_state = DllStructCreate("struct;long x;long y;long color;long z;long gridsize;boolean camlock;boolean draglock;endstruct") - DllStructSetData($singleton_demo_state, "x", 0) - DllStructSetData($singleton_demo_state, "y", 0) - DllStructSetData($singleton_demo_state, "z", 0) - DllStructSetData($singleton_demo_state, "color", $GLOBAL_INITIAL_XHAIR_COLOR) - DllStructSetData($singleton_demo_state, "gridsize", $GLOBAL_INITIAL_GRIDSIZE) - DllStructSetData($singleton_demo_state, "camlock", true) - DllStructSetData($singleton_demo_state, "draglock", false) - return $singleton_demo_state -EndFunc - -Func DemoSingletonState($init=null) ; todo: refactor to take device handle, and return the corresponding handle when queried. - Local Static $singleton_demo_state = InitializeSingletonState() - if $init then InitializeSingletonState() - return $singleton_demo_state ; by default just fetch address to struct -EndFunc - -Func DemoStartupProcedure(ByRef $ref_hWnd, ByRef $ref_hHBITMAP, ByRef $ref_hDC, ByRef $ref_hDC_Backbuffer, ByRef $ref_oDC_Obj, ByRef $ref_hGfxCtxt, ByRef $ref_hPen, ByRef $mouse) - Local $arr[4] - $arr[0] = ProgramCommand("demo_render_width") - $arr[1] = ProgramCommand("demo_render_height") - $arr[0] = $arr[0]>640?round($arr[0]):640 - $arr[1] = $arr[1]>480?round($arr[1]):480 - $arr[2] = round((@DeskTopWidth-$arr[0])/2) - $arr[3] = round((@DeskTopHeight-$arr[1])/2) - BackupPointerSpeedAndAccel($mouse) - DisablePointerSpeedAndAccel() - DemoSingletonState(true) ; ask it to initialize state -; $ref_hWnd = GUICreate($i18n_demo_wintitle, @DeskTopWidth,@DeskTopHeight,0,0,$WS_POPUP,34078728) - - $ref_hWnd = GUICreate($i18n_demo_wintitle, $arr[0], $arr[1], $arr[2], $arr[3], $WS_POPUP) - GUISetBkColor($COLOR_BLACK, $ref_hWnd) - GUISetIcon($GLOBAL_PROGRAM_ICON_PATH,229) - FrameCounterSingleton(False, $ref_hWnd) - AdlibRegister ( "FrameCounterUpdate" , 1000 ) - -; ------------------ adapted example Autoit Code from https://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_BitBlt.htm ------------------ - ;create a faster buffered graphics frame set for smoother gfx object movements - _GDIPlus_Startup() ;initialize GDI+ - Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($arr[0],$arr[1]) ;create an empty bitmap - $ref_hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) ;convert GDI+ bitmap to GDI bitmap - _GDIPlus_BitmapDispose($hBitmap) ;delete GDI+ bitmap because not needed anymore - $ref_hDC = _WinAPI_GetDC($ref_hWnd) ;get device context from GUI - $ref_hDC_Backbuffer = _WinAPI_CreateCompatibleDC($ref_hDC) ;creates a memory device context compatible with the specified device - $ref_oDC_Obj = _WinAPI_SelectObject($ref_hDC_Backbuffer, $ref_hHBITMAP) ;selects an object into the specified device context - $ref_hGfxCtxt = _GDIPlus_GraphicsCreateFromHDC($ref_hDC_Backbuffer) ;create a graphics object from a device context (DC) -; _GDIPlus_GraphicsSetSmoothingMode($ref_hGfxCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;set smoothing mode (8 X 4 box filter) -; _GDIPlus_GraphicsSetPixelOffsetMode($ref_hGfxCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) - $ref_hPen = _GDIPlus_PenCreate() ;create a pen object - GUISetState(@SW_SHOW, $ref_hWnd) - -#cs - $g_framelabel = GUICtrlCreateLabel("Press ESC to Exit",0,0,100,100) ; it's global because adlib needs to access it - GUICtrlSetBkColor($g_framelabel,$GUI_BKCOLOR_TRANSPARENT) - GUICtrlSetColor($g_framelabel,0x00ff00) - AdlibRegister ( "FrameCounterUpdate" , 1000 ) - GUICtrlCreateLabel("Click MB2 to toggle camera mode. While unlocked, push cursor against screen edge to move camera, hold MB3 to pan camera, hold MB1 to drag camera.",(@DeskTopWidth-600)/2,@DeskTopHeight-40,600,40,$SS_Center) - GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT) - GUICtrlSetColor(-1,0x00ff00) - GUICtrlSetFont (-1, 12) -#ce - -; experimental huge cursor -; TODO: Seems that even larger cursors are possible if not loading from .cur https://stackoverflow.com/questions/70704210/is-a-cursor-greater-than-512x512-pixels-in-size-possible -; https://stackoverflow.com/questions/46014692/windows-cursor-size-bigger-than-maximum-available -; https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadimagea no need to specify size if not requesting defaultsize -Global $hWhiteCursor = DllCall($user32dll,"handle","LoadImage", "handle", Null, "str", @ScriptDir & "\assets\cursors\white.cur", "uint", 2, "int", 0, "int", 0, "uint", 0x00000010) -Global $hLimeCursor = DllCall($user32dll,"handle","LoadImage", "handle", Null, "str", @ScriptDir & "\assets\cursors\lime.cur", "uint", 2, "int", 0, "int", 0, "uint", 0x00000010) -Global $hCyanCursor = DllCall($user32dll,"handle","LoadImage", "handle", Null, "str", @ScriptDir & "\assets\cursors\cyan.cur", "uint", 2, "int", 0, "int", 0, "uint", 0x00000010) -Global $hYellowCursor = DllCall($user32dll,"handle","LoadImage", "handle", Null, "str", @ScriptDir & "\assets\cursors\yellow.cur", "uint", 2, "int", 0, "int", 0, "uint", 0x00000010) -GUIRegisterMsg($WM_SETCURSOR,OnMessage) - Return $arr -EndFunc - -Func DemoWinddownProcedure(ByRef $ref_hWnd, ByRef $ref_hHBITMAP, ByRef $ref_hDC, ByRef $ref_hDC_Backbuffer, ByRef $ref_oDC_Obj, ByRef $ref_hGfxCtxt, ByRef $ref_hPen, ByRef $mouse) - AdlibUnRegister ( "FrameCounterUpdate" ) - FrameCounterSingleton(False, Null) - - _GDIPlus_PenDispose($ref_hPen) - _WinAPI_SelectObject($ref_hDC_Backbuffer, $ref_oDC_Obj) - _GDIPlus_GraphicsDispose($ref_hGfxCtxt) - _WinAPI_DeleteObject($ref_hHBITMAP) - _WinAPI_ReleaseDC($ref_hWnd, $ref_hDC) - - GUIDelete($ref_hWnd) - RestorePointerSpeedAndAccel($mouse) - -GUIRegisterMsg($WM_SETCURSOR,"") -Local $delWhite = DllCall($user32dll,"bool","DestroyCursor","handle",$hWhiteCursor[0]) -Local $delLime = DllCall($user32dll,"bool","DestroyCursor","handle",$hLimeCursor[0]) -Local $delCyan = DllCall($user32dll,"bool","DestroyCursor","handle",$hCyanCursor[0]) -Local $delYellow = DllCall($user32dll,"bool","DestroyCursor","handle",$hYellowCursor[0]) -;MsgBox(0,"",$delWhite[0] & "," & $delLime[0] & "," & $delCyan[0] & "," & $delYellow[0]) -EndFunc - - - -Func DemoDrawRoutine(Const $ctx, Const $pen, Const $width, Const $height) - Local Static $statePtr = DemoSingletonState() - Local $lineXpos, $lineYpos, $modceil - Local $currentX = DllStructGetData($statePtr,"x") - Local $currentY = DllStructGetData($statePtr,"y") - Local $currentZ = DllStructGetData($statePtr,"z") - Local $currentColor = DllStructGetData($statePtr,"color") - Local $modunit = DllStructGetData($statePtr,"gridsize") - - _GDIPlus_GraphicsClear($ctx) ; sets canvas to black - _GDIPlus_PenSetWidth($pen, 1) ; set pen size - _GDIPlus_PenSetColor($pen, 0xFF808080) ; grey grid - $modceil = $modunit*ceiling($height/$modunit/2) ; how many whole grid units needed to cover the window - for $i=-$modceil to $modceil step $modunit - $lineYpos = $height/2+$i - mod($currentY,$modunit) -; $lineYpos = Mod(Mod($i-$currentY,$modceil)+$modceil,$modceil) - _GDIPlus_GraphicsDrawLine($ctx, 0, $lineYpos, $width-1, $lineYpos, $pen) ; horizontal lines, from 0 to width-1 at ypos - next - $modceil = $modunit*ceiling($width/$modunit/2) ; how many whole grid units needed to cover the window - for $i=-$modceil to $modceil step $modunit - $lineXpos = $width/2+$i - mod($currentX,$modunit) -; $lineXpos = Mod(Mod($i-$currentX,$modceil)+$modceil,$modceil) - _GDIPlus_GraphicsDrawLine($ctx, $lineXpos, 0, $lineXpos, $height-1, $pen) ; vertical lines, from 0 to height-1 at xpos - next -#cs - _GDIPlus_PenSetColor($pen, $currentColor) ; xhair color - _GDIPlus_GraphicsDrawLine($ctx, 0, $height/2, $width, $height/2, $pen) - _GDIPlus_GraphicsDrawLine($ctx, $width/2, 0, $width/2, $height, $pen) -#ce - -EndFunc - - - -Func Demo($toggle = null, $cursorlock=null) - Local Static $ref_hWnd, $ref_hHBITMAP, $ref_hDC, $ref_hDC_Backbuffer, $ref_oDC_Obj, $ref_hGfxCtxt, $ref_hPen - Local Static $imgDim[4], $aPoint[3][2], $mouse=[10, 0, 0, 0] , $renderUnlocked=false - Local Static $submodebackup=3 - if $toggle then ; this must be checked before the render case, because $renderunlocked is stateful - if $renderUnlocked then ; end the demo - $renderUnlocked = false ; do this first in case main loop calls - _MouseTrap() - DemoWinddownProcedure($ref_hWnd, $ref_hHBITMAP, $ref_hDC, $ref_hDC_Backbuffer, $ref_oDC_Obj, $ref_hGfxCtxt, $ref_hPen, $mouse ) - SetDeviceSubscriptionMode($submodebackup) - else ; start the demo - $submodebackup = GetDeviceSubscriptionMode() - SetDeviceSubscriptionMode(3+BitAND(4,$submodebackup)) - Local $arr = DemoStartupProcedure( $ref_hWnd, $ref_hHBITMAP, $ref_hDC, $ref_hDC_Backbuffer, $ref_oDC_Obj, $ref_hGfxCtxt, $ref_hPen, $mouse ) - $imgDim[0]=$arr[0] - $imgDim[1]=$arr[1] - $imgDim[2]=$arr[2] - $imgDim[3]=$arr[3] -$aPoint[0][0] = 0 -$aPoint[0][1] = 0 -$aPoint[1][0] = $arr[0] -$aPoint[1][1] = 0 -$aPoint[2][0] = 0 -$aPoint[2][1] = $arr[1] - $g_mousetrap_bound[0]=$imgDim[2] - $g_mousetrap_bound[1]=$imgDim[3] - $g_mousetrap_bound[2]=$imgDim[0]+$imgDim[2] - $g_mousetrap_bound[3]=$imgDim[1]+$imgDim[3] - _MouseTrap(Int($imgDim[2]+$imgDim[0]/2),Int($imgDim[3]+$imgDim[1]/2),Int($imgDim[2]+$imgDim[0]/2)+1,Int($imgDim[3]+$imgDim[1]/2)+1) ; lock to halflength positions of viewport - GUISetCursor(16,1) - DllCall($user32dll, "handle", "SetCursor", "handle", $hLimeCursor[0]) - $renderUnlocked = true ; do this last - endif - elseif $renderUnlocked and $toggle=null then ; called from main loop. Note that we only run on main loop calls, otherwise the processing gets clogged - DemoDrawRoutine($ref_hGfxCtxt, $ref_hPen, $imgDim[0], $imgDim[1]) ; might need to add in ways to alter the image dimensions upon notification, which involves resizing the buffer allocation too and not just changing numbers - _WinAPI_BitBlt($ref_hDC, 0, 0, $imgDim[0],$imgDim[1], $ref_hDC_Backbuffer, 0, 0, $SRCCOPY) ;copy backbuffer to screen (GUI) -;_WinAPI_PlgBlt($ref_hDC, $aPoint, $ref_hDC_backbuffer, 0, 0, $imgDim[0], $imgDim[1]) - FrameCounterSingleton() - elseif not ($cursorlock=null) then ; lock/unlock cursor, need stateful data of window size/position. Low priority, latency doesn't matter so put it in elseif - if $cursorlock then ; lock to center of screen - _MouseTrap(Int($imgDim[2]+$imgDim[0]/2),Int($imgDim[3]+$imgDim[1]/2),Int($imgDim[2]+$imgDim[0]/2)+1,Int($imgDim[3]+$imgDim[1]/2)+1) - else ; lock to boundary of render - _MouseTrap($g_mousetrap_bound[0], $g_mousetrap_bound[1], $g_mousetrap_bound[2], $g_mousetrap_bound[3]) - endif - endif - Return $renderUnlocked ; if called specifically with false then just queries state -EndFunc - -Func FrameCounterSingleton($update=null, $ref_hWnd=null) - Local Static $demowindow = null, $counter=0 - Switch $update - Case True ; update framecounter display - Local $accumulated = $counter - $counter -= $accumulated - WinSetTitle($demowindow, "", "Demo " & $accumulated & "fps (" & $g_rawinput_queued & "/" & $g_rawinput_maxindex+1 & ")" ) - Case False ; refresh reference - $demowindow = $ref_hWnd - Case Null ; add framecount - $counter += 1 - EndSwitch -EndFunc - -Func FrameCounterUpdate() - FrameCounterSingleton(true) -EndFunc - -Func PanCamera() - Local Static $singleton_cache = DemoSingletonState() - Local $cursorpos = MouseGetPos() - Local $sendX = round(($cursorpos[0]-$g_middle_drag[0])/5) - Local $sendY = round(($cursorpos[1]-$g_middle_drag[1])/5) - MoveMouseDelta($sendX,$sendY,$singleton_cache) -EndFunc - Func CmdExitProgram() Exit #cs @@ -949,7 +559,7 @@ Func CmdScriptStartStop($start=null) Local $nowtime = _NowCalc() $gReportFileMkb = FileOpen("logs\" & _CleanupFileName($nowtime) & "\data.csv", 9) $gReportFileLst = FileOpen("logs\" & _CleanupFileName($nowtime) & "\list.txt", 9) - FileWrite($gReportFileMkb, "### NOTE: take the OS-provided timestamp with a grain of salt, as they are only reported in 16 or 10 ms increments. To get accurate interrupt timing of GetMessage() returns, use QueryPerformanceCounter instead. ###" & @CRLF) + FileWrite($gReportFileMkb, "### QueryPerformanceFrequency = " & $PERFORMANCE_FREQUENCY & " Hz ###" & @CRLF) FileWrite($gReportFileLst, _ "================" & @CRLF & _ "Initial HID List" & @CRLF & _ @@ -970,9 +580,9 @@ Func CmdScriptStartStop($start=null) EndFunc Func CmdUnlockProcessing($state, $hWnd = $g_hForm) -; GUIRegisterMsg( $WM_INPUT, '' ) - OnMessage($hWnd, $WM_NOTIFY, null, $state) -; If $state then GUIRegisterMsg( $WM_INPUT, OnMessage ) +; GUIRegisterMsg( 0xFF, '' ) + WndProc($hWnd, $WM_NOTIFY, null, $state) +; If $state then GUIRegisterMsg( 0xFF, WndProc ) EndFunc Func CmdDemoQuit() diff --git a/src/bin/assets/hidusagetable.ini b/src/bin/assets/hidusagetable.ini index ac761de..059bf4d 100644 --- a/src/bin/assets/hidusagetable.ini +++ b/src/bin/assets/hidusagetable.ini @@ -306,10 +306,278 @@ page=CONSUMER 0004=MICROPHONE 0005=HEADPHONE 0006=GRAPHIC EQUALIZER +;07 to 1f reserved +0020=+10 +0021=+100 +0022=AM/PM +;23 to 2f reserved +0030=POWER +0031=RESET +0032=SLEEP +0033=SLEEP AFTER +0034=SLEEP MODE +0035=ILLUMINATION +0036=FUNCTION BUTTONS +;37 to 3f reserved +0040=MENU +0041=MENU PICK +0042=MENU UP +0043=MENU DOWN +0044=MENU LEFT +0045=MENU RIGHT +0046=MENU ESCAPE +0047=MENU VALUE INCREASE +0048=MENU VALUE DECREASE +;49 to 5f reserved +0060=DATA ON SCREEN +0061=CLOSED CAPTION +0062=CLOSED CAPTION SELECT +0063=VCR/TV +0064=BROADCAST MODE +0065=SNAPSHOT +0066=STILL +0067=PICTURE-IN-PICTURE TOGGLE +0068=PICTURE-IN-PICTURE SWAP +0069=RED MENU BUTTON +006A=GREEN MENU BUTTON +006B=BLUE MENU BUTTON +006C=YELLOW MENU BUTTON +006D=ASPECT +006E=3D MODE SELECT +006F=DISPLAY BRIGHTNESS INCREMENT +0070=DISPLAY BRIGHTNESS DECREMENT +0071=DISPLAY BRIGHTNESS +0072=DISPLAY BACKLIGHT TOGGLE +0073=DISPLAY SET BRIGHTNESS TO MINIMUM +0074=DISPLAY SET BRIGHTNESS TO MAXIMUM +0075=DISPLAY SET AUTO BRIGHTNESS +0076=CAMERA ACCESS ENABLED +0077=CAMERA ACCESS DISABLED +0078=CAMERA ACCESS TOGGLE +0079=KEYBOARD BRIGHTNESS INCREMENT +007A=KEYBOARD BRIGHTNESS DECREMENT +007B=KEYBOARD BACKLIGHT SET LEVEL +007C=KEYBOARD BACKLIGHT OOC +007D=KEYBOARD BACKLIGHT SET MINIMUM +007E=KEYBOARD BACKLIGHT SET MAXIMUM +007F=KEYBOARD BACKLIGHT AUTO +0080=SELECTION +0081=ASSIGN SELECTION +0082=MODE STEP +0083=RECALL LAST +0084=ENTER CHANNEL +0085=ORDER MOVIE +0086=CHANNEL +0087=MEDIA SELECTION +0088=MEDIA SELECT COMPUTER +0089=MEDIA SELECT TV +008A=MEDIA SELECT WWW +008B=MEDIA SELECT DVD +008C=MEDIA SELECT TELEPHONE +008D=MEDIA SELECT PROGRAM GUIDE +008E=MEDIA SELECT VIDEO PHONE +008F=MEDIA SELECT GAMES +0090=MEDIA SELECT MESSAGES +0091=MEDIA SELECT CD +0092=MEDIA SELECT VCR +0093=MEDIA SELECT TUNER +0094=QUIT +0095=HELP +0096=MEDIA SELECT TAPE +0097=MEDIA SELECT CABLE +0098=MEDIA SELECT SATELLITE +0099=MEDIA SELECT SECURITY +009A=MEDIA SELECT HOME +009B=MEDIA SELECT CALL +009C=CHANNEL INCREMENT +009D=CHANNEL DECREMENT +009E=MEDIA SELECT SAP +;9f reserved +00A0=VCR PLUS +00A1=ONCE +00A2=DAILY +00A3=WEEKLY +00A4=MONTHLY +;a5 to af reserved +00B0=PLAY +00B1=PAUSE +00B2=RECORD +00B3=FAST FORWARD +00B4=REWIND +00B5=SCAN NEXT TRACK +00B6=SCAN PREVIOUS TRACK +00B7=STOP +00B8=EJECT +00B9=RANDOM PLAY +00BA=SELECT DISC +00BB=ENTER DISC +00BC=REPEAT +00BD=TRACKING +00BE=TRACK NORMAL +00BF=SLOW TRACKING +00C0=FRAME FORWARD +00C1=FRAME BACK +00C2=MARK +00C3=CLEAR MARK +00C4=REPEAT FROM MARK +00C5=RETURN TO MARK +00C6=SEARCH MARK FORWARD +00C7=SEARCH MARK BACKWARDS +00C8=COUNTER RESET +00C9=SHOW COUNTER +00CA=TRACKING INCREMENT +00CB=TRACKING DECREMENT +00CC=STOP/EJECT +00CD=PLAY/PAUSE +00CE=PLAY/SKIP +00CF=VOICE COMMAND +00D0=INVOKE CAPTURE INTERFACE +00D1=START OR STOP GAME RECORDING +00D2=HISTORICAL GAME CAPTURE +00D3=CAPTURE GAME SCREENSHOT +00D4=SHOW OR HIDE RECORDING INDICATOR +00D5=START OR STOP MICROPHONE CAPTURE +00D6=START OR STOP CAMERA CAPTURE +00D7=START OR STOP GAME BROADCAST +00D8=START OR STOP VOICE DICTATION SESSION +00D9=INVOKE/DISMISS EMOJI PICKER +;da to df reserved +00E0=VOLUME +00E1=BALANCE +00E2=MUTE +00E3=BASS +00E4=TREBLE +00E5=BASE BOOST +00E6=SURROUND MODE +00E7=LOUDNESS +00E8=MPX +00E9=VOLUME INCREMENT +00EA=VOLUME DECREMENT +;eb to ef reserved +00F0=SPEED SELECT +00F1=PLAYBACK SPEED +00F2=STANDARD PLAY +00F3=LONG PLAY +00F4=EXTENDED PLAY +00F5=SLOW +;f6 to ff reserved ; incomplete [000D] page=DIGITIZERS -; incomplete +0000=UNDEFINED +0001=DIGITIZER +0002=PEN +0003=LIGHT PEN +0004=TOUCH SCREEN +0005=TOUCH PAD +0006=WHITEBOARD +0007=COORDINATE MEASUREING MACHINE +0008=3D DIGITIZER +0009=STEREO PLOTTER +000A=ARTICULATED ARM +000B=ARMATURE +000C=MULTIPLE POINT DIGITIZER +000D=FREE SPACE WANT +000E=DEVICE CONFIGURATION +000F=CAPACITIVE HEAT MAP DIGITIZER +;10 to 1f reserved +0020=STYLUS +0021=PUCK +0022=FINGER +0023=DEVICE SETTINGS +0024=CHARACTER GESTURES +;25 to 2f reserved +0030=TIP PRESSURE +0031=BARREL PRESSURE +0032=IN RANGE +0033=TOUCH +0034=UNTOUCH +0035=TAP +0036=QUALITY +0037=DATA VALID +0038=TRANSDUCER INDEX +0039=TABLET FUNCTION KEYS +003A=PROGRAM CHANGE KEYS +003B=BATTERY STRENGTH +003C=INVERT +003D=X TILT +003E=Y TILT +003F=AZIMUTH +0040=ALTITUDE +0041=TWIST +0042=TIP SWITCH +0043=SECONDARY TIP SWITCH +0044=BARREL SWITCH +0045=ERASER +0046=TABLET PICK +0047=TOUCH VALID +0048=WIDTH +0049=HEIGHT +;4a to 50 reserved +0051=CONTACT IDENTIFIER +0052=DEVICE MODE +0053=DEVICE IDENTIFIER +0054=CONTACT COUNT +0055=CONTACT COUNT MAXIMUM +0056=SCAN TIME +0057=SURFACE SWITCH +0058=BUTTON SWITCH +0059=PAD TYPE +005A=SECONDARY BARREL SWITCH +005B=TRANSDUCER SERIAL NUMBER +005C=PREFERRED COLOR +005D=PREFERRED COLOR IS LOCKED +005E=PREFERRED LINE WIDTH +005F=PREFERRED LINE WIDTH IS LOCKED +0060=LATENCY MODE +0061=GESTURE CHARACTER QUALITY +0062=CHARACTER GESTURE DATA LENGTH +0063=CHARACTER GESTURE DATA +0064=GESTURE CHARACTER ENCODING +0065=UTF8 CHARACTER GESTURE ENCODING +0066=UTF16 LITTLE ENDIAN CHARACTER GESTURE ENCODING +0067=UTF16 BIG ENDIAN CHARACTER GESTURE ENCODING +0068=UTF32 LITTLE ENDIAN CHARACTER GESTURE ENCODING +0069=UTF32 BIG ENDIAN CHARACTER GESTURE ENCODING +006A=CAPACITIVE HEAT MAP PROTOCOL VENDOR ID +006B=CAPACITIVE HEAT MAP PROTOCOL VERSION +006C=CAPACITIVE HEAT MAP FRAME DATA +006D=GESTURE CHARACTER ENABLE +006E=TRANSDUCER SERIAL NUMBER PART 2 +006F=NO PREFERRED COLOR +0070=PREFERRED LINE STYLE +0071=PREFERRED LINE STYLE IS LOCKED +0072=INK +0073=PENCIL +0074=HIGHLIGHTER +0075=CHISEL MARKER +0076=BRUSH +0077=NO PREFERENCE +;78 to 7f reserved +0080=DIGITIZER DIAGNOSTIC +0081=DIGITIZER ERROR +0082=ERR NORMAL STATUS +0083=ERR TRANSDUCERS EXCEEDED +0084=ERR FULL TRANS FEATURES UNAVAILABLE +0085=ERR CHARGE LOW +;86 to 8f reserved +0090=TRANSDUCER SOFTWARE INFO +0091=TRANSDUCER VENDOR ID +0092=TRANSDUCER PRODUCT ID +0093=DEVICE SUPPORTED PROTOCOLS +0094=TRANSDUCER SUPPORTED PROTOCOLS +0095=NO PROTOCOL +0096=WACOM AES PROTOCOL +0097=USI PROTOCOL +0098=MICROSOFT PEN PROTOCOL +;99 to 9f reserved +00A0=SUPPORTED REPORT RATES +00A1=REPORT RATE +00A2=TRANSDUCER CONNECTED +00A3=SWITCH DISABLED +00A4=SWITCH UNIMPLEMENTED +00A5=TRANSDUCER SWITCHES +;a6 to ffff reserved [000E] page=HAPTICS 0000=UNDEFINED @@ -333,7 +601,7 @@ page=HAPTICS 1006=WAVEFORM PRESS 1007=WAVEFORM RELEASE [000F] -page=PID +page=PHYSICAL INPUT DEVICE [0010] page=UNICODE [0012] @@ -415,25 +683,25 @@ page=BRAILLE DISPLAY page=LIGHTING AND ILLUMINATION ; incomplete [0080] -page=USB MONITOR +page=MONITOR ; incomplete [0081] -page=USB ENUMERATED VALUES +page=MONITOR ENUMERATED ; incomplete [0082] page=VESA VIRTUAL CONTROLS ; incomplete [0084] -page=POWER DEVICE +page=POWER ; incomplete [0085] page=BATTERY SYSTEM ; incomplete [008C] -page=BAR CODE SCANNER +page=BARCODE SCANNER ; incomplete [008D] -page=WEIGHING SCALE +page=SCALES ; incomplete [008E] page=MAGNETIC STRIPE READER diff --git a/src/bin/demo.au3 b/src/bin/demo.au3 new file mode 100644 index 0000000..45ba83b --- /dev/null +++ b/src/bin/demo.au3 @@ -0,0 +1,299 @@ +#include +#include +#include + +Func UpdateMovementCmd($lLastX, $lLastY, $posX, $posY, $handle=null) + Local Static $singleton_cache = DemoSingletonState() ; TODO: refactor DemoSingletonState to take device handle and return struct address, then change this line to Local instead of Local Static (and pass handle) + Local $cameramode = DllStructGetData($singleton_cache, "camlock") + Local $drag_state = DllStructGetData($singleton_cache, "draglock") + Local $pan_state = DllStructGetData($singleton_cache, "panlock") + Local $sendX=0, $sendY=0, $residueX=0, $residueY=0 + if $cameramode or $pan_state then ; camlock mode true, FPS-like + $sendX = $lLastX + $sendY = $lLastY + else ; camlock mode false, RTS-like + if $drag_state then + ; drag pan + $sendX = -$lLastX + $sendY = -$lLastY + else + ; edge pan + if ($posX+$lLastX<$singleton_cache.left) or ($posX+$lLastX>$singleton_cache.right-1) then $sendX=$lLastX + if ($posY+$lLastY<$singleton_cache.top) or ($posY+$lLastY>$singleton_cache.bottom-1) then $sendY=$lLastY + endif + endif + Local $fac = PointerMultiplier(10,0,$singleton_cache.dpi) + $sendX = $residueX + $sendX*$fac + $sendY = $residueY + $sendY*$fac + $residueX = $sendX - Int($sendX) + $residueY = $sendY - Int($sendY) + MoveMouseDelta(Int($sendX), Int($sendY), $singleton_cache) +EndFunc + +Func UpdateButtonState($usButtonFlags, $usButtonData, $lastX, $lastY, $handle=null) + Local Static $singleton_cache = DemoSingletonState() ; TODO: refactor DemoSingletonState to take device handle and return struct address, then change this line to Local instead of Local Static (and pass handle) + Local $xhairstate = DllStructGetData($singleton_cache, "color") + Local $cameramode = DllStructGetData($singleton_cache, "camlock") + Local $drag_state = DllStructGetData($singleton_cache, "draglock") + + ; crosshair color state. Is latency sensitive + if BitAND($usButtonFlags,1) then $xhairstate = BitOR( $xhairstate, 0x000000ff ) ; add blue to state + if BitAND($usButtonFlags,2) then $xhairstate = BitAND($xhairstate, 0xffffff00 ) ; subtract blue from state + if BitAND($usButtonFlags,4) then $xhairstate = $cameramode ? BitAND($xhairstate, 0x00ff00ff ) : BitOR( $xhairstate, 0xff00ff00 ) + if BitAND($usButtonFlags,16) then $xhairstate = BitOR( $xhairstate, 0x00ff0000 ) ; add red to state + if BitAND($usButtonFlags,32) then $xhairstate = BitAND($xhairstate, 0xff00ffff ) ; subtract red from state + if $usButtonFlags then + SetCrosshairColor($xhairstate, $singleton_cache) ; only update color if actual commands are sent + Switch BitAND(0x00ffffff,$xhairstate) + Case 0x00ffffff + SetCursor($hWhiteCursor, $user32dll) + Case 0x0000ffff + SetCursor($hCyanCursor, $user32dll) + Case 0x00ffff00 + SetCursor($hYellowCursor, $user32dll) + Case 0x0000ff00 + SetCursor($hLimeCursor, $user32dll) + EndSwitch + endif + + ; camera mode toggle check. Not latency-sensitive + if BitAND($usButtonFlags,1) then DragLockSetState(true, $singleton_cache) + if BitAND($usButtonFlags,2) then DragLockSetState(false, $singleton_cache) + if BitAND($usButtonFlags,4) then CameraLockSetState(not $cameramode, $singleton_cache) + if BitAND($usButtonFlags,16) then PanLockSetState(True,$lastX,$lastY,$singleton_cache) + if BitAND($usButtonFlags,32) then PanLockSetState(False,$lastX,$lastY,$singleton_cache) + if BitAND($usButtonFlags,1024) then ChangeZoomLevel($usButtonData, $singleton_cache) +EndFunc + +Func CameraLockSetState($lock=Null,$target=Null) + Local Static $cache=DemoSingletonState() + Local $_ = IsDllStruct($target) ? $target : $cache + Local $mode = $_.camlock + If Not (Null=$lock) Then + DllStructSetData($_, "camlock", $lock) + $mode = $lock + EndIf + If $mode Then + _LockCursor(Int(($_.left+$_.right)/2),Int(($_.top+$_.bottom)/2),$user32dll) + Else + _TrapCursor($_.left,$_.top,$_.right,$_.bottom,$user32dll) + EndIf +EndFunc + +Func DragLockSetState($lock, $ptr) + DllStructSetData($ptr, "draglock", $lock) +EndFunc + +Func PanLockSetState($lock, $x, $y, $_) + DllStructSetData($_, "panlock", $lock) + $_.panlock = $lock + If $_.camlock Then Return + If $lock Then + _LockCursor($x,$y,$user32dll) + Else + _TrapCursor($_.left,$_.top,$_.right,$_.bottom,$user32dll) + EndIf +EndFunc + +Func MoveMouseDelta($dx, $dy, $ptr) + DllStructSetData($ptr, "x", DllStructGetData($ptr, "x")+$dx) + DllStructSetData($ptr, "y", DllStructGetData($ptr, "y")+$dy) +EndFunc + +Func SetCrosshairColor($color, $ptr) + DllStructSetData($ptr, "color", $color) +EndFunc + +Func ChangeZoomLevel($step, $ptr) + Local Const $scale = 2 + Local Const $period = 12*120 + Local $newmodx, $newmody, $newmodz, $newsize, $magnify + Local $oldmodx = DllStructGetData($ptr,"x") + Local $oldmody = DllStructGetData($ptr,"y") + Local $oldmodz = DllStructGetData($ptr,"z") + Local $oldsize = DllStructGetData($ptr,"gridsize") + $newmodz = $oldmodz + $step + $newmodz = $newmodz - $period*round($newmodz/$period) + $newsize = round( $GLOBAL_INITIAL_GRIDSIZE*exp(log($scale)*$newmodz/$period) ) + $magnify = exp(log($scale)*($step)/$period) + if $newmodz-$oldmodz < $step then + $newmody = round(mod($oldmody+$oldsize/$scale,$oldsize)*$magnify) + $newmodx = round(mod($oldmodx+$oldsize/$scale,$oldsize)*$magnify) + elseif $newmodz-$oldmodz > $step then + $newmody = round(mod($oldmody*$magnify-$newsize/$scale,$newsize)) + $newmodx = round(mod($oldmodx*$magnify-$newsize/$scale,$newsize)) + else ; if not wrapped + $newmody = round(mod($oldmody,$oldsize)*$magnify) + $newmodx = round(mod($oldmodx,$oldsize)*$magnify) + endif + DllStructSetData( $ptr, "x", $newmodx ) ; renormalize + DllStructSetData( $ptr, "y", $newmody ) ; renormalize + DllStructSetData( $ptr, "z", $newmodz ) + DllStructSetData( $ptr, "gridsize", $newsize ) +EndFunc + +Func InitializeSingletonState() + Local Static $singleton_demo_state = DllStructCreate("long x;long y;long color;long z;long gridsize;boolean camlock;boolean draglock;boolean panlock;long left;long top;long right;long bottom;uint dpi") + DllStructSetData($singleton_demo_state, "x", 0) + DllStructSetData($singleton_demo_state, "y", 0) + DllStructSetData($singleton_demo_state, "z", 0) + DllStructSetData($singleton_demo_state, "color", $GLOBAL_INITIAL_XHAIR_COLOR) + DllStructSetData($singleton_demo_state, "gridsize", $GLOBAL_INITIAL_GRIDSIZE) + DllStructSetData($singleton_demo_state, "camlock", true) + DllStructSetData($singleton_demo_state, "draglock", false) + return $singleton_demo_state +EndFunc + +Func DemoSingletonState($init=null) ; todo: refactor to take device handle, and return the corresponding handle when queried. + Local Static $singleton_demo_state = InitializeSingletonState() + if $init then InitializeSingletonState() + return $singleton_demo_state ; by default just fetch address to struct +EndFunc + +Func DemoStartupProcedure(ByRef $ref_hWnd, ByRef $ref_hHBITMAP, ByRef $ref_hDC, ByRef $ref_hDC_Backbuffer, ByRef $ref_oDC_Obj, ByRef $ref_hGfxCtxt, ByRef $ref_hPen, ByRef $mouse) + Local $arr[4] + $arr[0] = ProgramCommand("demo_render_width") + $arr[1] = ProgramCommand("demo_render_height") + $arr[0] = $arr[0]>640?round($arr[0]):640 + $arr[1] = $arr[1]>480?round($arr[1]):480 + $arr[2] = round((@DeskTopWidth-$arr[0])/2) + $arr[3] = round((@DeskTopHeight-$arr[1])/2) + BackupPointerSpeedAndAccel($mouse) + DisablePointerSpeedAndAccel() + SplashTextOn ( "Please wait...", "Preparing buffer, please wait...", $arr[0],$arr[1],$arr[2],$arr[3],1) + InitBigCursors($arr[0],$arr[1]) + SplashOff() + DemoSingletonState(true) ; ask it to initialize state + $ref_hWnd = GUICreate($i18n_demo_wintitle, $arr[0], $arr[1], $arr[2], $arr[3], 0x80000000) + GUISetBkColor($COLOR_BLACK, $ref_hWnd) + GUISetIcon($GLOBAL_PROGRAM_ICON_PATH) + FrameCounterSingleton(False, $ref_hWnd) + AdlibRegister ( "FrameCounterUpdate" , 1000 ) + +; ------------------ adapted example Autoit Code from https://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_BitBlt.htm ------------------ + ;create a faster buffered graphics frame set for smoother gfx object movements + _GDIPlus_Startup() ;initialize GDI+ + Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($arr[0],$arr[1]) ;create an empty bitmap + $ref_hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) ;convert GDI+ bitmap to GDI bitmap + _GDIPlus_BitmapDispose($hBitmap) ;delete GDI+ bitmap because not needed anymore + $ref_hDC = _WinAPI_GetDC($ref_hWnd) ;get device context from GUI + $ref_hDC_Backbuffer = _WinAPI_CreateCompatibleDC($ref_hDC) ;creates a memory device context compatible with the specified device + $ref_oDC_Obj = _WinAPI_SelectObject($ref_hDC_Backbuffer, $ref_hHBITMAP) ;selects an object into the specified device context + $ref_hGfxCtxt = _GDIPlus_GraphicsCreateFromHDC($ref_hDC_Backbuffer) ;create a graphics object from a device context (DC) +; _GDIPlus_GraphicsSetSmoothingMode($ref_hGfxCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;set smoothing mode (8 X 4 box filter) +; _GDIPlus_GraphicsSetPixelOffsetMode($ref_hGfxCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) + $ref_hPen = _GDIPlus_PenCreate() ;create a pen object + GUISetState(@SW_DISABLE, $g_hForm) + GUISetState(@SW_SHOW, $ref_hWnd) + GUIRegisterMsg($WM_SETCURSOR,WndProc) + Return $arr +EndFunc + +Func DemoWinddownProcedure(ByRef $ref_hWnd, ByRef $ref_hHBITMAP, ByRef $ref_hDC, ByRef $ref_hDC_Backbuffer, ByRef $ref_oDC_Obj, ByRef $ref_hGfxCtxt, ByRef $ref_hPen, ByRef $mouse) + AdlibUnRegister ( "FrameCounterUpdate" ) + FrameCounterSingleton(False, Null) + + _GDIPlus_PenDispose($ref_hPen) + _WinAPI_SelectObject($ref_hDC_Backbuffer, $ref_oDC_Obj) + _GDIPlus_GraphicsDispose($ref_hGfxCtxt) + _WinAPI_DeleteObject($ref_hHBITMAP) + _WinAPI_ReleaseDC($ref_hWnd, $ref_hDC) + + + GUIDelete($ref_hWnd) + RestorePointerSpeedAndAccel($mouse) + + GUIRegisterMsg($WM_SETCURSOR,"") + GUISetState(@SW_ENABLE, $g_hForm) +EndFunc + + + +Func DemoDrawRoutine(Const $ctx, Const $pen, Const $width, Const $height) + Local Static $statePtr = DemoSingletonState() + Local $lineXpos, $lineYpos, $modceil + Local $currentX = DllStructGetData($statePtr,"x") + Local $currentY = DllStructGetData($statePtr,"y") + Local $currentZ = DllStructGetData($statePtr,"z") + Local $currentColor = DllStructGetData($statePtr,"color") + Local $modunit = DllStructGetData($statePtr,"gridsize") + + _GDIPlus_GraphicsClear($ctx) ; sets canvas to black + _GDIPlus_PenSetWidth($pen, 1) ; set pen size + _GDIPlus_PenSetColor($pen, 0xFF808080) ; grey grid + $modceil = $modunit*ceiling($height/$modunit/2) ; how many whole grid units needed to cover the window + for $i=-$modceil to $modceil step $modunit + $lineYpos = $height/2+$i - mod($currentY,$modunit) +; $lineYpos = Mod(Mod($i-$currentY,$modceil)+$modceil,$modceil) + _GDIPlus_GraphicsDrawLine($ctx, 0, $lineYpos, $width-1, $lineYpos, $pen) ; horizontal lines, from 0 to width-1 at ypos + next + $modceil = $modunit*ceiling($width/$modunit/2) ; how many whole grid units needed to cover the window + for $i=-$modceil to $modceil step $modunit + $lineXpos = $width/2+$i - mod($currentX,$modunit) +; $lineXpos = Mod(Mod($i-$currentX,$modceil)+$modceil,$modceil) + _GDIPlus_GraphicsDrawLine($ctx, $lineXpos, 0, $lineXpos, $height-1, $pen) ; vertical lines, from 0 to height-1 at xpos + next +#cs + _GDIPlus_PenSetColor($pen, $currentColor) ; xhair color + _GDIPlus_GraphicsDrawLine($ctx, 0, $height/2, $width, $height/2, $pen) + _GDIPlus_GraphicsDrawLine($ctx, $width/2, 0, $width/2, $height, $pen) +#ce + +EndFunc + + + +Func Demo($toggle = null) + Local Static $ref_hWnd, $ref_hHBITMAP, $ref_hDC, $ref_hDC_Backbuffer, $ref_oDC_Obj, $ref_hGfxCtxt, $ref_hPen + Local Static $imgDim[4], $mouse=[10, 0, 0, 0] , $renderUnlocked=false + Local Static $submodebackup=3 + if $toggle then ; this must be checked before the render case, because $renderunlocked is stateful + if $renderUnlocked then ; end the demo + $renderUnlocked = false ; do this first in case main loop calls + _FreeCursor() + DemoWinddownProcedure($ref_hWnd, $ref_hHBITMAP, $ref_hDC, $ref_hDC_Backbuffer, $ref_oDC_Obj, $ref_hGfxCtxt, $ref_hPen, $mouse ) + SetDeviceSubscriptionMode($submodebackup) + else ; start the demo + $submodebackup = GetDeviceSubscriptionMode() + SetDeviceSubscriptionMode(3+BitAND(4,$submodebackup)) + Local $arr = DemoStartupProcedure( $ref_hWnd, $ref_hHBITMAP, $ref_hDC, $ref_hDC_Backbuffer, $ref_oDC_Obj, $ref_hGfxCtxt, $ref_hPen, $mouse ) + $imgDim[0]=$arr[0] + $imgDim[1]=$arr[1] + $imgDim[2]=$arr[2] + $imgDim[3]=$arr[3] + Local $demoState = DemoSingletonState() + $demoState.dpi = GetDpiForWindow($ref_hWnd, $user32dll) + $demoState.left = $imgDim[2] + $demoState.top = $imgDim[3] + $demoState.right = $imgDim[0]+$imgDim[2] + $demoState.bottom = $imgDim[1]+$imgDim[3] + _LockCursor(Int($imgDim[2]+$imgDim[0]/2),Int($imgDim[3]+$imgDim[1]/2),$user32dll) + GUISetCursor(16,1,$ref_hWnd) + SetCursor($hLimeCursor, $user32dll) + $renderUnlocked = true ; do this last + endif + elseif $renderUnlocked and $toggle=null then ; called from main loop. Note that we only run on main loop calls, otherwise the processing gets clogged + DemoDrawRoutine($ref_hGfxCtxt, $ref_hPen, $imgDim[0], $imgDim[1]) ; might need to add in ways to alter the image dimensions upon notification, which involves resizing the buffer allocation too and not just changing numbers + _WinAPI_BitBlt($ref_hDC, 0, 0, $imgDim[0],$imgDim[1], $ref_hDC_Backbuffer, 0, 0, $SRCCOPY) + FrameCounterSingleton() + endif + Return $renderUnlocked ; if called specifically with false then just queries state +EndFunc + +Func FrameCounterSingleton($update=null, $ref_hWnd=null) + Local Static $demowindow = null, $counter=0 + Switch $update + Case True ; update framecounter display + Local $accumulated = $counter + $counter -= $accumulated + WinSetTitle($demowindow, "", "Demo " & $accumulated & "fps (" & $g_rawinput_queued & "/" & $g_rawinput_maxindex+1 & ")" ) + Case False ; refresh reference + $demowindow = $ref_hWnd + Case Null ; add framecount + $counter += 1 + EndSwitch +EndFunc + +Func FrameCounterUpdate() + FrameCounterSingleton(true) +EndFunc \ No newline at end of file diff --git a/src/bin/hidhelpers.au3 b/src/bin/hidhelpers.au3 index e1c52f4..475948f 100644 --- a/src/bin/hidhelpers.au3 +++ b/src/bin/hidhelpers.au3 @@ -26,6 +26,95 @@ Func CheckUniqueUsageAndAdd(ByRef $arr, $page, $id) $arr[$total-1][1]=$id EndFunc +Func MakeLogString($raw,$misc) + Local $_ = RAWINPUT($raw) + Local $s = $misc.qpc, $p = DllStructCreate('short x;short y;',DllStructGetPtr($misc)) + If IsDllStruct($_) Then + Switch $_.Type + Case 0 + $s &= ",mouse=," & $_.hDevice + $s &= ", bflg=,0x" & Hex($_.ButtonFlags,4) + $s &= ", bdta=,0x" & Hex($_.ButtonData,4) + $s &= ", dx=," & $_.LastX + $s &= ", dy=," & $_.LastY + Case 1 + $s &= ",keybd=," & $_.hDevice + $s &= ", wmsg=,0x" & Hex($_.Message,4) + $s &= ", vkey=,0x" & Hex($_.VKey,2) + $s &= ", make=," & Hex($_.MakeCode,2) + $s &= ", flag=," & $_.Flags + Case 2 + $s &= ",hidev=," & $_.hDevice + $s &= ", byte=," & $_.SizeHid + $s &= ", ninp=," & $_.Count + For $i = 1 to $_.Count + Local $name = 'Input' & $i + $s &= ", " & $name & "=," & DllStructGetData($_,$name) + Next + EndSwitch + Else + $s &= ( $misc.wParam-1 ? ",remov=,0x" : ",arrve=,0x" ) + $s &= Hex($misc.lParam,16) & ", =,, =,, =,, =," + EndIf + Local Static $pos = DllStructCreate('short x;short y') + Local Static $write = DllStructCreate('dword;',DllStructGetPtr($pos)) + DllStructSetData($write,1,$misc.pt) + $s &= ", os=,(" & $pos.x & " " & $pos.y & " " & $misc.time & " " & $misc.info & ")" + Return $s & @CRLF +EndFunc + +Func MakeReportString($raw,$misc) + Local $_ = RAWINPUT($raw) + Local $s = _ + "== RAWINPUTHEADER ==" & @CRLF & _ + "Device Type: " & _deviceType($_.Type) & @CRLF & _ + "Report Size: " & $_.Size & " bytes" & @CRLF & _ + "Device Handle: " & $_.hDevice & @CRLF & _ + "Received in Background: " & ($_.wParam?'TRUE':'FALSE') & @CRLF & @CRLF + Switch $_.Type + Case 0 + $s &= _ + "== RAWMOUSE ==" & @CRLF & _ + "Delta: " & $_.LastX & ", " & $_.LastY & @CRLF & _ + "Flags: " & "0x" & Hex($_.Flags,4) & _usFlagsMouse($_.Flags) & @CRLF & _ + "Button Flag: " & "0x" & Hex($_.ButtonFlags,4) & _usButtonFlags($_.ButtonFlags) & @CRLF & _ + "Button Data: " & ($_.ButtonData>0?'+':'') & $_.ButtonData & @CRLF & _ + "Raw Buttons: " & "0x" & Hex($_.RawButtons,8) & @CRLF & _ + "Extra Info: " & "0x" & Hex($_.ExtraInformation,8) & @CRLF & @CRLF + Case 1 + $s &= _ + "== RAWKEYBOARD ==" & @CRLF & _ + "Make Code: " & "0x" & Hex($_.MakeCode,4) & @CRLF & _ + "Flags: " & "0x" & Hex($_.Flags,4) & _usFlagsKeyboard($_.Flags) & @CRLF & _ + "Reserved: " & "0x" & Hex($_.Reserved,4) & @CRLF & _ + "Virtual Key: " & "0x" & Hex($_.VKey,4) & _usVkey($_.VKey) & @CRLF & _ + "Win Message: " & "0x" & Hex($_.Message,8) & _uiMessage($_.Message) & @CRLF & _ + "Extra Info: " & "0x" & Hex($_.ExtraInfo,8) & @CRLF & @CRLF + Case 2 + $s &= _ + "== RAWHID ==" & @CRLF & _ + "Bytes per Input: " & $_.SizeHid & @CRLF & _ + "Number of Inputs: " & $_.Count & @CRLF + For $i = 1 to $_.Count + Local $name = 'Input' & $i + $s &= $name & ': ' & DllStructGetData($_,$name) & @CRLF + Next + $s &= @CRLF + EndSwitch + + Local $time = $misc.time ; from GetMessageTime() + Local $info = "0x"&Hex($misc.info, 8) ; from GetMessageExtraInfo() + Local Static $pos = DllStructCreate('short x;short y') + Local Static $write = DllStructCreate('dword;',DllStructGetPtr($pos)) + DllStructSetData($write,1,$misc.pt) + Return $s & _ + "== MSGINFO ==" & @CRLF & _ + "OS Timestamp: " & $time & " ms" & @CRLF & _ + "OS EvntCoord: " & $pos.x & ", " & $pos.y & @CRLF & _ + "OS ExtraInfo: " & $info ;& ", " & $deltaTime +EndFunc + + Func GetConnectedRawinputDevicesUsages($devflag) ; called by RawinputStateController to return a 2D array for registration processing ; UsagePage 0x01 = generic desktop controls; Usage 0x02 = mouse ; UsagePage 0x01 = generic desktop controls; Usage 0x06 = keyboard @@ -49,7 +138,6 @@ Func GetConnectedRawinputDevicesUsages($devflag) ; called by RawinputStateContro EndFunc Func GetConnectedRawinputDevicesInfoString($matchHandleFilter=null) - Local $tText Local $list = _WinAPI_EnumRawInputDevices() If IsArray($list) Then Switch $matchHandleFilter @@ -69,49 +157,89 @@ EndFunc Func GetDeviceInfoString($handle, $type) Local Const $hidtable = @ScriptDir & '\assets\hidusagetable.ini' - Local $tName, $tText = DllStructCreate('wchar[256]') - Local $device_info_string = 'Handle: ' & $handle & @CRLF + Local $tDevName = DllStructCreate('wchar[256]') + Local $outputString = 'Handle: ' & $handle & @CRLF - If _WinAPI_GetRawInputDeviceInfo($handle, $tText, DllStructGetSize($tText), $RIDI_DEVICENAME) Then - Local $name = DllStructGetData($tText, 1) - $device_info_string = $device_info_string & $name & @CRLF + If _WinAPI_GetRawInputDeviceInfo($handle, $tDevName, DllStructGetSize($tDevName), $RIDI_DEVICENAME) Then + Local $hidDll = DllOpen('hid.dll') + $outputString = $outputString & DllStructGetData($tDevName, 1) & @CRLF - Local $HIDHandle = _WinAPI_CreateFile( $name , $OPEN_EXISTING , 0 , BitOR($FILE_SHARE_READ,$FILE_SHARE_WRITE) , Null , Null ) + Local $HIDHandle = _WinAPI_CreateFile( DllStructGetData($tDevName, 1) , $OPEN_EXISTING , 0 , BitOR($FILE_SHARE_READ,$FILE_SHARE_WRITE) , Null , Null ) If $HIDHandle Then - $tName = DllStructCreate('struct;ULONG Size; USHORT VendorID; USHORT ProductID; USHORT VersionNumber;endstruct') - DllStructSetData($tName, 'Size', DllStructGetSize($tName)) - DllCall ( "Hid.dll", 'boolean', 'HidD_GetAttributes', _ - 'handle' , $HIDHandle , _ - 'struct*', $tName ) - Local $s_vend = 'VID_' & Hex(DllStructGetData($tName, 'VendorID'),4) - Local $s_prod = 'PID_' & Hex(DllStructGetData($tName, 'ProductID'),4) - Local $s_revi = 'REV_' & Hex(DllStructGetData($tName, 'VersionNumber'),4) - - $tName = DllStructCreate('wchar[126]') - DllCall ( "Hid.dll", 'boolean', 'HidD_GetManufacturerString', _ - 'handle' , $HIDHandle , _ - 'struct*', $tName, _ - 'ulong' , DllStructGetSize($tName) ) - if DllStructGetData($tName, 1) then $s_vend = $s_vend & ' (' & DllStructGetData($tName, 1) & ')' + Local $tHidAttr = DllStructCreate('struct;ULONG Size; USHORT VendorID; USHORT ProductID; USHORT VersionNumber;endstruct') + DllStructSetData($tHidAttr, 'Size', DllStructGetSize($tHidAttr)) + Local $aHidAttr = DllCall ( $hidDll, _ + 'boolean', 'HidD_GetAttributes', _ + 'handle' , $HIDHandle , _ + 'struct*', $tHidAttr ) + Local $tManuStr = DllStructCreate('wchar[126]') + Local $aManuStr = DllCall ( $hidDll, _ + 'boolean', 'HidD_GetManufacturerString', _ + 'handle' , $HIDHandle , _ + 'struct*', $tManuStr, _ + 'ulong' , DllStructGetSize($tManuStr) ) + Local $tProdStr = DllStructCreate('wchar[126]') + Local $aProdStr = DllCall ( $hidDll, _ + 'boolean', 'HidD_GetProductString', _ + 'handle' , $HIDHandle , _ + 'struct*', $tProdStr, _ + 'ulong' , DllStructGetSize($tProdStr) ) + Local $sVend = 'VID_' & Hex(DllStructGetData($tHidAttr, 'VendorID'),4) + Local $sProd = 'PID_' & Hex(DllStructGetData($tHidAttr, 'ProductID'),4) + Local $sRevi = 'REV_' & Hex(DllStructGetData($tHidAttr, 'VersionNumber'),4) + If DllStructGetData($tManuStr, 1) Then $sVend = $sVend & ' (' & DllStructGetData($tManuStr, 1) & ')' + if DllStructGetData($tProdStr, 1) then $sProd = $sProd & ' (' & DllStructGetData($tProdStr, 1) & ')' - DllCall ( "Hid.dll", 'boolean', 'HidD_GetProductString', _ - 'handle' , $HIDHandle , _ - 'struct*', $tName, _ - 'ulong' , DllStructGetSize($tName) ) - if DllStructGetData($tName, 1) then $s_prod = $s_prod & ' (' & DllStructGetData($tName, 1) & ')' + Local $tSeriStr = DllStructCreate('wchar[126]') + Local $aSeriStr = DllCall ( $hidDll, _ + 'boolean', 'HidD_GetSerialNumberString', _ + 'handle' , $HIDHandle , _ + 'struct*', $tSeriStr, _ + 'ulong' , DllStructGetSize($tSeriStr) ) + Local $tNumBuff = DllStructCreate("int") + Local $aNumBuff = DllCall ( $hidDll, _ + 'boolean', 'HidD_GetNumInputBuffers', _ + 'handle' , $HIDHandle , _ + 'struct*', $tNumBuff ) - $device_info_string = $device_info_string & _ - ' Vendor: ' & $s_vend & @CRLF & _ - ' Product: ' & $s_prod & @CRLF & _ - ' Version: ' & $s_revi & @CRLF - - Local $serial = DllCall ( "Hid.dll", 'boolean', 'HidD_GetSerialNumberString', _ - 'handle' , $HIDHandle , _ - 'struct*', $tName, _ - 'ulong' , DllStructGetSize($tName) ) - if $serial[0] then $device_info_string = $device_info_string & ' Serial#: ' & DllStructGetData($tName, 1) & @CRLF + If $aHidAttr[0] Then + $outputString = $outputString & _ + ' Vendor: ' & $sVend & @CRLF & _ + ' Product: ' & $sProd & @CRLF & _ + ' Version: ' & $sRevi & @CRLF + EndIf + If $aSeriStr[0] Then + $outputString = $outputString & _ + ' Serial#: ' & DllStructGetData($tSeriStr, 1) & @CRLF + EndIf + If $aNumBuff[0] Then + $outputString = $outputString & _ + ' Buffers: ' & DllStructGetData($tNumBuff, 1) & @CRLF + EndIf + ; The HID class driver requires a minimum of two input buffers. + ; On Windows 2000, the maximum number of input buffers that the HID class driver supports is 200, + ; and on Windows XP and later, the maximum number of input buffers that the HID class driver supports is 512. + ; The default number of input buffers is 32. +#cs + ; GUID_DEVINTERFACE_MOUSE {378de44c-56ef-11d1-bc8c-00a0c91405dd} + ; GUID_DEVINTERFACE_KEYBOARD {884b96c3-56ef-11d1-bc8c-00a0c91405dd} + ; GUID_DEVINTERFACE_HID {4d1e55b2-f16f-11cf-88cb-001111000030} + Local $tIntGuid = DllStructCreate("dword Data1; word Data2; word Data3; byte Data4[8]") + DllCall ( $hidDll, _ + "none", "HidD_GetHidGuid", _ + "struct*", $tIntGuid ) + Local $sGUID = Hex(DllStructGetData($tIntGuid,'Data1'),8) & '-' & _ + Hex(DllStructGetData($tIntGuid,'Data2'),4) & '-' & _ + Hex(DllStructGetData($tIntGuid,'Data3'),4) & '-' & _ + Hex(DllStructGetData($tIntGuid,'Data4'),12) + If $sGUID Then + $outputString = $outputString & _ + ' Interface: ' & $sGUID & @CRLF + EndIf +#ce EndIf _WinAPI_CloseHandle($HIDHandle) + DllClose($hidDll) EndIf Switch $type @@ -119,7 +247,7 @@ Func GetDeviceInfoString($handle, $type) Local Const $mouseRIDstruct='dword Size;dword Type;struct;dword Id;dword NumberOfButtons;dword SampleRate;int HasHorizontalWheel;endstruct;dword Unused[2];' Local $devInf = DllStructCreate($mouseRIDstruct) ; $tagRID_INFO_MOUSE in WinAPISys.au3 has a typo If _WinAPI_GetRawInputDeviceInfo($handle, $devInf, DllStructGetSize($devInf), $RIDI_DEVICEINFO ) Then - $device_info_string = $device_info_string & _ + $outputString = $outputString & _ ' HID Type: ' & _deviceType(DllStructGetData($devInf, 'Type')) & @CRLF & _ ' Id: ' & '0x' & Hex(DllStructGetData($devInf, 'Id'),4) & _mouseIdType(DllStructGetData($devInf, 'Id')) & @CRLF & _ ' Buttons: ' & DllStructGetData($devInf, 'NumberOfButtons') & @CRLF & _ @@ -131,7 +259,7 @@ Func GetDeviceInfoString($handle, $type) Local $devInf = DllStructCreate($keyboardRIDstruct) ; $tagRID_INFO_KEYBOARD in WinAPISys.au3 has a typo If _WinAPI_GetRawInputDeviceInfo($handle, $devInf, DllStructGetSize($devInf), $RIDI_DEVICEINFO ) Then - $device_info_string = $device_info_string & _ + $outputString = $outputString & _ ' HID Type: ' & _deviceType(DllStructGetData($devInf, 'Type')) & @CRLF & _ ' KbType: ' & '0x' & Hex(DllStructGetData($devInf, 'KbType'),2) & _kbType(DllStructGetData($devInf, 'KbType')) & @CRLF & _ ' KbSubType: ' & '0x' & Hex(DllStructGetData($devInf, 'KbSubType'),2) & @CRLF & _ @@ -145,16 +273,29 @@ Func GetDeviceInfoString($handle, $type) Local $devInf = DllStructCreate($hidRIDstruct) ; $tagRID_INFO_HID in WinAPISys.au3 has a typo If _WinAPI_GetRawInputDeviceInfo($handle, $devInf, DllStructGetSize($devInf), $RIDI_DEVICEINFO ) Then - $device_info_string = $device_info_string & _ + $outputString = $outputString & _ ' HID Type: ' & _deviceType(DllStructGetData($devInf, 'Type')) & @CRLF & _ ' VendorID: ' & Hex(DllStructGetData($devInf, 'VendorId'),4) & @CRLF & _ ' ProductID: ' & Hex(DllStructGetData($devInf, 'ProductId'),4) & @CRLF & _ ' Revision: ' & Hex(DllStructGetData($devInf, 'VersionNumber'),4) & @CRLF & _ ' UsagePage: ' & _HIDUsageString($hidtable, DllStructGetData($devInf, 'UsagePage')) & @CRLF & _ ' UsageID: ' & _HIDUsageString($hidtable, DllStructGetData($devInf, 'UsagePage'), DllStructGetData($devInf, 'Usage')) & @CRLF + EndIf EndSwitch - Return $device_info_string +#cs + Local $presize = DllCall('user32.dll','uint','GetRawInputDeviceInfo','handle',$handle,'uint',0x20000005,'struct*',Null,'uint*',Null)[4] + Local $predata = DllCall('user32.dll','uint','GetRawInputDeviceInfo','handle',$handle,'uint',0x20000005,'struct*',DllStructCreate('byte['&$presize&']'),'uint*',$presize)[3] + If $presize Then + $outputString &= ' Preparsed Data (' & $presize & ' bytes): ' & @CRLF & ' ' + For $i=1 To $presize + $outputString &= Hex(DllStructGetData($predata,1,$i),2) & ' ' + If Not Mod($i,4) Then $outputString &= @CRLF & ' ' + Next + $outputString &= @CRLF + EndIf +#ce + Return $outputString ; code adapted from https://www.autoitscript.com/forum/topic/190157-how-can-i-use-_winapi_getrawinputdeviceinfo-to-get-hid-device-info/?do=findComment&comment=1364904 ; https://stackoverflow.com/questions/12656236/how-to-get-human-readable-name-for-rawinput-hid-device ; https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/hidclass-hardware-ids-for-top-level-collections diff --git a/src/bin/mischelper.au3 b/src/bin/mischelper.au3 index fc9ac99..f9ceeaf 100644 --- a/src/bin/mischelper.au3 +++ b/src/bin/mischelper.au3 @@ -1,14 +1,3 @@ -; from https://www.autoitscript.com/forum/topic/168698-changing-a-windows-icon/?do=findComment&comment=1233266 -Func _WinSetIcon($hWnd, $sFile, $iIndex = 0) - Local $tIcons = DllStructCreate("ptr Data") - DllCall("shell32.dll", "uint", "ExtractIconExW", "wstr", $sFile, "int", $iIndex, "struct*", 0, "struct*", $tIcons, "uint", 1) - If @error Then Return SetError(1, 0, 0) - Local $hIcon = DllStructGetData($tIcons, "Data") - _SendMessage($hWnd, 0x0080, 1, $hIcon ) ;$WM_SETICON = 0x0080 - _WinAPI_DestroyIcon($hIcon) - Return 1 -EndFunc - ; from https://www.autoitscript.com/forum/topic/183294-disable-right-click-on-control/?do=findComment&comment=1316532 Func EditCallback( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData ) ; If $iMsg <> $WM_RBUTTONUP then call next function in subclass chain (this forwards messages to Edit control) @@ -55,38 +44,6 @@ Func DisablePointerSpeedAndAccel() _SetPointerAccel($struct) EndFunc -Func _GetPointerSpeed() - Local $struct = DllStructCreate("uint speed") - DllCall("user32.dll", "none", "SystemParametersInfo", _ - "uint", 0x0070, _ - "uint", 0, _ - "ptr" , DllStructGetPtr($struct), _ - "uint", 0) - return DllStructGetData($struct,"speed") -EndFunc - -Func _GetPointerAccel() - Local $struct = DllStructCreate("uint thresh1;uint thresh2;uint accel") - DllCall("user32.dll", "none", "SystemParametersInfo", _ - "uint", 0x0003, _ - "uint", 0, _ - "ptr" , DllStructGetPtr($struct), _ - "uint", 0) - return $struct -EndFunc - -Func _SetPointerSpeed($val, $flag=0) - DllCall("user32.dll", "none", "SystemParametersInfo", _ - "uint", 0x0071, _ - "uint", 0, _ - "uint", $val, _ - "uint", $flag) -EndFunc - -Func _SetPointerAccel($struct, $flag=false) - DllCall("user32.dll", "none", "SystemParametersInfo", _ - "uint", 0x0004, _ - "uint", 0, _ - "ptr" , DllStructGetPtr($struct), _ - "uint", $flag) +Func PointerMultiplier($spd,$acc,$dpi) + Return ( $acc ? $spd/10 : ( $spd<4 ? BitShift(1,-$spd)/64 : 1 + ($spd-10)/BitShift(8,Int($spd/10.5)) ) ) * $dpi/96 EndFunc \ No newline at end of file diff --git a/src/bin/rawhelpers.au3 b/src/bin/rawhelpers.au3 new file mode 100644 index 0000000..29251fa --- /dev/null +++ b/src/bin/rawhelpers.au3 @@ -0,0 +1,62 @@ +Func RAWINPUT($raw) + Switch DllStructGetData(RAWINPUTHEADER($raw),'Type') + Case 0 + Return RAWMOUSE($raw) + Case 1 + Return RAWKEYBOARD($raw) + Case 2 + Return RAWHID($raw) + EndSwitch +EndFunc + +Func RAWINPUTHEADER($raw) + Local Static $tag = 'struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;' + Return DllStructCreate( $tag , DllStructGetPtr($raw) ) +EndFunc + +Func RAWMOUSE($raw) + Local Static $tag = 'struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;' & _ + 'ushort Flags;ushort Alignment;ushort ButtonFlags;short ButtonData;ulong RawButtons;long LastX;long LastY;ulong ExtraInformation;' + Return DllStructCreate( $tag , DllStructGetPtr($raw) ) +EndFunc + +Func RAWKEYBOARD($raw) + Local Static $tag = 'struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;' & _ + 'ushort MakeCode;ushort Flags;ushort Reserved;ushort VKey;uint Message;ulong ExtraInformation;' + Return DllStructCreate( $tag , DllStructGetPtr($raw) ) +EndFunc + +Func RAWHID($raw) + Local Static $pre = 'struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;' & _ + 'dword SizeHid;dword Count;' + Local $ptr = DllStructGetPtr($raw) + Local $_ = DllStructCreate($pre,$ptr) + Local $s = DllStructGetData($_,'SizeHid') + Local $tag = $pre + For $i=1 to DllStructGetData($_,'Count') + $tag &= 'byte Input' & $i & '[' & $s & '];' + Next + Return DllStructCreate( $tag , $ptr ) +EndFunc + +Func _RawInputFetchData($lParam, $_dll='user32.dll') + Local Static $HEADSIZE = DllStructGetSize(DllStructCreate('struct;dword;dword;handle;wparam;endstruct;')) + Local $size = DllCall($_dll,'uint','GetRawInputData','handle',$lParam,'uint',0x10000003,'struct*',Null,'uint*',Null,'uint',$HEADSIZE)[4] + Return DllCall ( $_dll, _ + 'uint' , 'GetRawInputData', _ + 'handle' , $lParam, _ + 'uint' , 0x10000003, _ + 'struct*' , DllStructCreate('byte[' & $size & ']'), _ + 'uint*' , $size, _ + 'uint' , $HEADSIZE )[3] +EndFunc + +Func _RawInputRegisterDevice($page, $usage, $flags, $target) + Local Static $TAG = 'ushort;ushort;dword;hwnd',$SIZE = DllStructGetSize(DllStructCreate($TAG)) + Local $struct = DllStructCreate($TAG) + DllStructSetData($struct, 1, $page) + DllStructSetData($struct, 2, $usage) + DllStructSetData($struct, 3, $flags) + DllStructSetData($struct, 4, $target) + Return DllCall('user32.dll','bool','RegisterRawInputDevices','struct*',$struct,'uint',1,'uint',$SIZE)[0] +EndFunc \ No newline at end of file diff --git a/src/bin/winapihelpers.au3 b/src/bin/winapihelpers.au3 new file mode 100644 index 0000000..2ea8f15 --- /dev/null +++ b/src/bin/winapihelpers.au3 @@ -0,0 +1,106 @@ +#include-once +; here goes misc winapi functions not defined in dedicated files +; this lets me avoid having to include autoit's udfs +; CONVENTION: +; prefix underscore for custom instances of winapi function +; no underscore for verbatim wrap of winapi function + +Func QueryPerformanceCounter($_dll='kernel32.dll') + Return DllCall($_dll,'bool','QueryPerformanceCounter','Int64*',Null)[1] +EndFunc + +Func QueryPerformanceFrequency($_dll='kernel32.dll') + Return DllCall($_dll,'bool','QueryPerformanceFrequency','Int64*',Null)[1] +EndFunc + +Func GetDpiForWindow($hWnd, $_dll='user32.dll') + Return DllCall($_dll, "uint", "GetDpiForWindow", "handle", $hWnd)[0] +EndFunc + +Func SetCursor($hCursor=Null, $_dll='user32.dll') + Return DllCall($_dll, "handle", "SetCursor", "handle", $hCursor)[0] +EndFunc + +Func CreateIconIndirect($fIcon,$xHotspot,$yHotspot,$hbmMask,$hbmColor,$_dll='user32.dll') + Local $iconinfo = DllStructCreate('bool fIcon;dword xHotspot;dword yHotspot;handle hbmMask;handle hbmColor;') + $iconinfo.fIcon = $fIcon + $iconinfo.xHotspot = $xHotspot + $iconinfo.yHotspot = $yHotspot + $iconinfo.hbmMask = $hbmMask + $iconinfo.hbmColor = $hbmColor + Return DllCall($_dll,'handle','CreateIconIndirect','struct*',$iconinfo)[0] +EndFunc + +Func DestroyCursor($hCursor, $_dll='user32.dll') + Return DllCall($_dll,"bool","DestroyCursor","handle",$hCursor)[0] +EndFunc + +Func GetClipCursor($_dll='user32.dll') + Return DllCall($_dll,'bool','GetClipCursor','struct*',DllStructCreate('long left;long top;long right;long bottom;'))[1] +Endfunc + +Func ClipCursor($rect,$_dll='user32.dll') + Return DllCall($_dll,'bool','ClipCursor','struct*',$rect)[0] +EndFunc + +Func _FreeCursor($_dll='user32.dll') + Return ClipCursor(Null,$_dll) +EndFunc + +Func _TrapCursor($left,$top,$right,$bottom,$_dll='user32.dll') + Local Static $rect = DllStructCreate('long;long;long;long;') + DllStructSetData($rect,1,$left) + DllStructSetData($rect,2,$top) + DllStructSetData($rect,3,$right) + DllStructSetData($rect,4,$bottom) + Return ClipCursor($rect,$_dll) +EndFunc + +Func _LockCursor($x,$y,$_dll='user32.dll') + Return _TrapCursor($x,$y,$x+1,$y+1,$_dll) +EndFunc + +Func _LoadBigCursor($filepath,$_dll='user32.dll') + Return _ + DllCall($_dll, "handle", "LoadImage", _ + "handle", Null, _ ; hInstance null to load my own image + "str", $filepath, _ + "uint", 2, _ ; type cursor + "int", 0, _ ; width zero to use the actual file width + "int", 0, _ ; height zero to use the actual file height + "uint", 0x00000010)[0] ; LR_LOADFROMFILE +EndFunc + +Func _GetPointerSpeed($_dll='user32.dll') + Return _ + DllCall($_dll, "bool", "SystemParametersInfo", _ + "uint", 0x0070, _ + "uint", 0, _ + "uint*", Null, _ + "uint", 0)[3] +EndFunc + +Func _GetPointerAccel($_dll='user32.dll') + Return _ + DllCall($_dll, "bool", "SystemParametersInfo", _ + "uint", 0x0003, _ + "uint", 0, _ + "struct*", DllStructCreate("uint thresh1;uint thresh2;uint accel;"), _ + "uint", 0)[3] +EndFunc + +Func _SetPointerSpeed($spd, $flag=0, $_dll='user32.dll') + DllCall($_dll, "bool", "SystemParametersInfo", _ + "uint", 0x0071, _ + "uint", 0, _ + "uint", $spd, _ + "uint", $flag) +EndFunc + +Func _SetPointerAccel($acc, $flag=0, $_dll='user32.dll') + DllCall($_dll, "bool", "SystemParametersInfo", _ + "uint", 0x0004, _ + "uint", 0, _ + "struct*", $acc, _ + "uint", $flag) +EndFunc