How
I would integrate raw input and the easier/simpler method for non-advanced users are entirely different. For instance, this is "optimized" for the chat button on my mouse (since it's the only button I need to detect):
Code:
DetectHiddenWindows, On
Process, Exist
Script_Hwnd := WinExist("ahk_class AutoHotkey ahk_pid " ErrorLevel)
DetectHiddenWindows, Off
;...
RegisterRawInputDevice(1, 12, Script_Hwnd)
;....
return
;...
RegisterRawInputDevice(Usage, UsagePage, hwnd)
{
VarSetCapacity(dev, 12, 0)
NumPut(UsagePage, dev, 0, "UShort")
NumPut(Usage, dev, 2, "UShort")
NumPut(0x100, dev, 4) ; dwFlags = RIDEV_INPUTSINK (don't require foreground)
NumPut(hwnd, dev, 8)
if DllCall("RegisterRawInputDevices"
, "uint", &dev ; pRawInputDevices (pointer to an array of RAWINPUTDEVICE)
, "uint", 1 ; uiNumDevices
, "uint", 12) ; cbSize (size of a RAWINPUTDEVICE structure)
OnMessage(0xFF, "WM_INPUT")
}
WM_INPUT(wParam, lParam)
{
Static HoldingChat=0
Critical
; Get required buffer size.
DllCall("GetRawInputData", "uint", lParam, "uint", 0x10000003
, "uint", 0, "uint*", size, "uint", 16)
VarSetCapacity(raw, size, 0)
; Get raw input data from handle (lParam)
ret := DllCall("GetRawInputData", "uint", lParam, "uint", 0x10000003
, "uint", &raw, "uint*", size, "uint", 16, "int")
if (ErrorLevel or ret = -1)
return
type := NumGet(raw)
if type = 2 ; RIM_TYPEHID
{
if (NumGet(raw, 20) < 1) ; dwCount
return
if (NumGet(raw, 16) < 3) ; dwSizeHid - should be 5 for my device.
return
if (NumGet(raw, 25, "UShort") = 0x1BC) ; Chat button.
{
if (!HoldingChat) {
gosub ActivateLastFlashingWindow
HoldingChat = 1
}
}
else if (HoldingChat)
HoldingChat = 0
}
}
As you can see, there's barely any separation of implementation from the assigned action, so it isn't user-other-than-me-friendly.
What I want to know is: how would
you like to integrate raw input within your scripts? For instance,
Code:
hid:chat::msgbox chat pressed
would be the most abstract, but obviously won't work since it doesn't say which device, or what "chat" is.
Perhaps something like this?:
Code:
OnRawHid( Usage, UsagePage, Pattern, Label [, DeviceIndex=Any ] )
Pattern could be a regular expression, or a simple string such as "030000E200" (which would be my mute button.) I suppose for readability, optional spaces could be included: "03 00 00 E2 00".
"Why use a regular expression?" -- If I press mute while holding chat, I get the message "03 BC 01 E2 00", which is a combination of chat (BC 01) and mute (E2). So, for instance, I could say "^.{6}E2.{2}$" and that would match "030000E200" (mute), "03BC01E200" (chat+mute, or mute+chat), etc.
I suppose regular expressions aren't for "non-advanced users," though.