 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
MrB Guest
|
Posted: Sat Sep 15, 2007 1:02 am Post subject: |
|
|
So how would you integrate these HID raw data outputs - once you found them - into your autohotkey.ini?
The focus should be on an easy and simple integration for non-advanced users. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4473 Location: Qld, Australia
|
Posted: Sun Sep 16, 2007 7:42 am Post subject: |
|
|
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. |
|
| Back to top |
|
 |
MrB Guest
|
Posted: Fri Sep 21, 2007 10:26 pm Post subject: |
|
|
Hi lexikos, sorry for the delayed answer, I was out of town for the last days. | Quote: | | What I want to know is: how would you like to integrate raw input within your scripts? |
First of all, taking up Micha's comment, there should be a switch to turn HID support of, if not needed - to reduce the space autohotkey needs at runtime. There should also be a switch to set the HID-device to listen to or disable input from certain devices. Perhaps like this: | Code: | #DisableHIDSupport ;enabled by default
#OpenHIDforInput(Devicename, Usage, UsagePage) ;listen to all devices by default |
Second, I would prefer to keep the syntax that autohotkey uses for keys and use it accordingly for HID devices. Something like this:
| Code: | | 030000E200:: Msgbox, Mute was pressed |
To facilitate the learning process for the user, the section "key history and skript info" of autohotkey should contain 1) the necessary HID strings (in this case 030000E200)and 2) the device the string was obtained from.
Would be great if we could get this working and our comments find their way into the program... |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4473 Location: Qld, Australia
|
Posted: Sat Sep 22, 2007 2:50 am Post subject: |
|
|
Since I posted, I've been working on a RawInput function-library script, which I will use to make a (hopefully) user-friendly method of accepting raw input in a script. It won't be as easy as "hotkey::", but perhaps as easy as the hotkey command. (It'll need to be called from the auto-execute section to associate devices/data with labels.)
To test the functions, I wrote a GUI script (which will also be useful in determining what data a device sends.)
That shows all of the ways a device can be identified (atm.)
| Quote: | | #OpenHIDforInput(Devicename, Usage, UsagePage) | Unfortunately, it isn't easy to get a (useful) readable device name. Of some use, the Device Name shown on the GUI (and by Micha's script) contains a hint to a registry path. For instance, | Code: | | Device Name: \\?\HID#VID_046D&PID_C518&MI_01&Col01#7&231d2277&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} |
The registry key for this device can be found at | Code: | | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\HID\VID_046D&PID_C518&MI_01&Col01\7&231d2277&0&0000 | Unfortunately the only "readable name" I see is "HID-compliant consumer control device." Not very useful.
The Vendor ID (VID) and Product ID (PID) identify the device (in this case as a Logitech MX610.) To get a list of handles to matching devices, I can do: | Code: | | list := RawInput_FilterDevices("VID_046D PID_C518") | This gets the top three devices in the screenshot above. To identify the specific device I am after, I can do one of: | Code: | hDevice := RawInput_FilterDevices("VID_046D PID_C518 #3")
; or
hDevice := RawInput_FilterDevices("UP12 U1") ; UsagePage 0x000C = 12, Usage 1
; or a combination |
| Quote: | | First of all, taking up Micha's comment, there should be a switch to turn HID support of, if not needed | #DisableHIDSupport seems redundant, since OpenHIDforInput() would be required to tell AutoHotkey to register a device.
| Quote: | | - to reduce the space autohotkey needs at runtime. | I'm not sure exactly what space would be used, other than the space for each HID-hotkey, and the memory used by the raw input code itself.
Heh, it just occurred to me that whileis not a valid hotkey (at least, "doesn't exist in the current keyboard layout"), | Code: | 030000E200:
; and even
hid:12-1-3:030000E200: | are valid labels. Still, I think it would be best to include some indication of which device should trigger the HID-hotkey/label. (That is, if it were automatic/built-in.)
The level-of-ease I'm eventually aiming for is something like:- Open the GUI.
- Select a device (or all devices.)
- Press a button. Assuming it triggers an input event,
- Click the input event. This should generate code for quick insertion into a script, and possibly more specific details, like a filter to identify the device, and the data string alone.
Example code: | Code: | RawInput_Map("VID_046D PID_C518 UP12 U1", "03BC010000", "ClickedChatButton")
; or the easier-but-more-likely-to-eventually-conflict-with-something:
RawInput_Map("#3", "030000E200", "ClickedMuteButton")
;...
ClickedChatButton:
WinActivate, - Online
return
ClickedMuteButton:
Send {Volume_Mute} ; undo the button's native function
Send {Media_Play_Pause}
return | I'd use OnRawInput(), but that wouldn't be function-library compliant.
What has been delaying the script is this: a string like "030000E200" doesn't seem like a generic enough way of identifying a button. Additionally, it doesn't seem to provide much benefit over the existing scripts. For instance, where does the script you mentioned earlier fall short? |
|
| Back to top |
|
 |
Guest
|
Posted: Wed Dec 05, 2007 5:51 pm Post subject: |
|
|
| lexikos wrote: | | raw HID data is sent as a blob of binary data. For instance, one of the devices associated with my mouse sends "03 00 00 E2 00" for mute, "03 00 00 E9 00" for volume up, but "03 BC 01 E9 00" if I was already holding the chat button. It's not a simple "pressed/released this button" message, so adding generic support for it to AutoHotkey would be difficult. |
I have been playing with Raw Devices today, using my USB keyboard. I managed a limited success - I can get a list of HID devices, I can intercept (using WM_INPUT) any of them, and I can capture events for many keys on my keyboard. Unfortunatelly, AutoHotKey is able to capture those keys as well. I couldn't get a single "real raw" input from my keyboard (that is, a sequence of bytes similar to that you listed above) - all WM_INPUT messages came in the form of "slightly translated" RIM_TYPEKEYBOARD, none as "real raw" RIM_TYPEHID. Unfortunatelly, it doesn't seem like I can capture the extra keys - not even when I intercept the whole UsagePage 1
I hope I will have a better luck with my MX1000 (when I come back home where it sits). If I could capture at least SOME of the extra keys, it would be nice. |
|
| Back to top |
|
 |
tyxiang
Joined: 26 Nov 2008 Posts: 12
|
Posted: Wed Dec 17, 2008 1:10 pm Post subject: |
|
|
I used Lexikos's script for my remote control.
The remote control add a HID and a JoyStick in my PC. The script can get code from Joystick (Usage=5 and UsagePage=1).
But it can not get code from the HID (Usage=0 and UsagePage=65280).
Can you help me?
Thank you a lot. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|