initial
This commit is contained in:
@@ -0,0 +1,583 @@
|
||||
/*! TheGood
|
||||
AHKHID - An AHK implementation of the HID functions.
|
||||
Last updated: August 22nd, 2010
|
||||
|
||||
USING THE CONSTANTS:
|
||||
|
||||
If you explicitly #include AHKHID in your script, you will have all the constants available to you. Otherwise, if AHKHID is
|
||||
in your library folder and you do not wish to explicitly #include it, you can call AHKHID_UseConstants() to have the
|
||||
constants available to you.
|
||||
|
||||
FUNCTION LIST:
|
||||
_____________________
|
||||
AHKHID_UseConstants()
|
||||
|
||||
See the section above titled "USING THE CONSTANTS"
|
||||
___________________________________
|
||||
AHKHID_Initialize(bRefresh = False)
|
||||
|
||||
You don't have to call this function manually. It is automatically called by other functions to get the pointer of the
|
||||
RAWINPUTDEVICELIST struct array. However, if a new device is plugged in, you will have to refresh the listing by calling it
|
||||
with bRefresh = True. Returns -1 on error (with error message in ErrorLevel).
|
||||
____________________
|
||||
AHKHID_GetDevCount()
|
||||
|
||||
Returs the number of HID devices connected to this computer.
|
||||
Returns -1 on error (with error message in ErrorLevel).
|
||||
______________________
|
||||
AHKHID_GetDevHandle(i)
|
||||
|
||||
Returns the handle of device i (starts at 1).
|
||||
Mostly used internally for API calls.
|
||||
__________________________
|
||||
AHKHID_GetDevIndex(Handle)
|
||||
|
||||
Returns the index (starts at 1) of the device in the enumeration with matching handle.
|
||||
Returns 0 if not found.
|
||||
______________________________________
|
||||
AHKHID_GetDevType(i, IsHandle = False)
|
||||
|
||||
Returns the type of the device. See the RIM_ constants for possible values.
|
||||
If IsHandle is false, then i is considered the index (starts at 1) of the device in the enumeration.
|
||||
Otherwise it is the handle of the device.
|
||||
______________________________________
|
||||
AHKHID_GetDevName(i, IsHandle = False)
|
||||
|
||||
Returns the name of the device (or empty string on error, with error message in ErrorLevel).
|
||||
If IsHandle is false, then i is considered the index (starts at 1) of the device in the enumeration.
|
||||
Otherwise it is the handle of the device.
|
||||
____________________________________________
|
||||
AHKHID_GetDevInfo(i, Flag, IsHandle = False)
|
||||
|
||||
Retrieves info from the RID_DEVICE_INFO struct. To retrieve a member, simply use the corresponding flag. A list of flags
|
||||
can be found at the top of the script (the constants starting with DI_). Each flag corresponds to a member in the struct.
|
||||
If IsHandle is false, then i is considered the index (starts at 1) of the device in the enumeration. Otherwise it is the
|
||||
handle of the device. Returns -1 on error (with error message in ErrorLevel).
|
||||
|
||||
See Example 1 for an example on how to use it.
|
||||
_______________________________________________________________________________
|
||||
AHKHID_AddRegister(UsagePage = False, Usage = False, Handle = False, Flags = 0)
|
||||
|
||||
Allows you to queue up RAWINPUTDEVICE structures before doing the registration. To use it, you first need to initialize the
|
||||
variable by calling AHKHID_AddRegister(iNumberOfElements). To then add to the stack, simply call it with the parameters you
|
||||
want (eg. AHKHID_AddRegister(1,6,MyGuiHandle) for keyboards). When you're finally done, you just have to call
|
||||
AHKHID_Register() with no parameters. The function returns -1 if the struct is full. Redimensioning the struct will erase
|
||||
all previous structs added. On success, it returns the address of the array of structs (if you'd rather manipulate it
|
||||
yourself).
|
||||
|
||||
See Example 2 for an example on how to use it.
|
||||
|
||||
You will need to do this if you want to use advance features of the RAWINPUTDEVICE flags. For example, if you want to
|
||||
register all devices using Usage Page 1 but would like to exclude devices of Usage Page 1 using Usage 2 (keyboards), then
|
||||
you need to place two elements in the array. The first one is AHKHID_AddRegister(1,0,MyGuiHandle,RIDEV_PAGEONLY) and the
|
||||
second one is AHKHID_AddRegister(1,2,MyGuiHandle,RIDEV_EXCLUDE).
|
||||
|
||||
Tip: Have a look at all the flags you can use (see the constants starting with RIDEV_). The most useful is RIDEV_INPUTSINK.
|
||||
Tip: Set Handle to 0 if you want the WM_INPUT messages to go to the window with keyboard focus.
|
||||
Tip: To unregister, use the flag RIDEV_REMOVE. Note that you also need to use the RIDEV_PAGEONLY flag if the TLC was
|
||||
registered with it.
|
||||
____________________________________________________________________________
|
||||
AHKHID_Register(UsagePage = False, Usage = False, Handle = False, Flags = 0)
|
||||
|
||||
This function can be used in two ways. If no parameters are specified, it will use the RAWINPUTDEVICE array created through
|
||||
AHKHID_AddRegister() and register. Otherwise, it will register only the specified parameters. For example, if you just want
|
||||
to register the mouse, you can simply do AHKHID_Register(1,2,MyGuiHandle). Returns 0 on success, returns -1 on error (with
|
||||
error message in ErrorLevel).
|
||||
|
||||
See Example 2 for an example on how to use it with the RAWINPUTDEVICE.
|
||||
See Example 3 for an example on how to use it only with the specified parameters.
|
||||
____________________________________
|
||||
AHKHID_GetRegisteredDevs(ByRef uDev)
|
||||
|
||||
This function allows you to get an array of the TLCs that have already been registered.
|
||||
It fills uDev with an array of RAWINPUTDEVICE and returns the number of elements in the array.
|
||||
Returns -1 on error (with error message in ErrorLevel).
|
||||
|
||||
See Example 2 for an example on how to use it.
|
||||
______________________________________
|
||||
AHKHID_GetInputInfo(InputHandle, Flag)
|
||||
|
||||
This function is used to retrieve the data upon receiving WM_INPUT messages. By passing the lParam of the WM_INPUT (0xFF00)
|
||||
messages, it can retrieve all the members of the RAWINPUT structure, except the raw data coming from HID devices (use
|
||||
AHKHID_GetInputData for that). To retrieve a member, simply specify the flag corresponding to the member you want, and call
|
||||
the function. A list of all the flags can be found at the top of this script (the constants starting with II_). Returns -1
|
||||
on error (with error message in ErrorLevel).
|
||||
|
||||
See Example 2 for an example on how to use it to retrieve each member of the structure.
|
||||
See Example 3 for an example on how to interpret members which represent flags.
|
||||
|
||||
Tip: You have to use Critical in your message function or you might get invalid handle errors.
|
||||
Tip: You can check the value of wParam to know if the application was in the foreground upon reception (see RIM_INPUT).
|
||||
_____________________________________________
|
||||
AHKHID_GetInputData(InputHandle, ByRef uData)
|
||||
|
||||
This function is used to retrieve the data sent by HID devices of type RIM_TYPEHID (ie. neither keyboard nor mouse) upon
|
||||
receiving WM_INPUT messages. CAUTION: it does not check if the device is indeed of type HID. It is up to you to do so (you
|
||||
can use GetInputInfo for that). Specify the lParam of the WM_INPUT (0xFF00) message and the function will put in uData the
|
||||
raw data received from the device. It will then return the size (number of bytes) of uData. Returns -1 on error (with error
|
||||
message in ErrorLevel).
|
||||
|
||||
See Example 2 for an example on how to use it (although you need an HID device of type RIM_TYPEHID to test it).
|
||||
|
||||
*/
|
||||
|
||||
AHKHID_Included := True
|
||||
AHKHID_SetConstants:
|
||||
;______________________________________
|
||||
;Flags you can use in AHKHID_GetDevInfo
|
||||
;http://msdn.microsoft.com/en-us/library/ms645581
|
||||
DI_DEVTYPE := 4 ;Type of the device. See RIM_ constants.
|
||||
|
||||
DI_MSE_ID := 8 ;ID for the mouse device.
|
||||
DI_MSE_NUMBEROFBUTTONS := 12 ;Number of buttons for the mouse.
|
||||
DI_MSE_SAMPLERATE := 16 ;Number of data points per second. This information may not be applicable for every
|
||||
;mouse device.
|
||||
DI_MSE_HASHORIZONTALWHEEL := 20 ;Vista and later only: TRUE if the mouse has a wheel for horizontal scrolling;
|
||||
;otherwise, FALSE.
|
||||
|
||||
DI_KBD_TYPE := 8 ;Type of the keyboard.
|
||||
DI_KBD_SUBTYPE := 12 ;Subtype of the keyboard.
|
||||
DI_KBD_KEYBOARDMODE := 16 ;Scan code mode.
|
||||
DI_KBD_NUMBEROFFUNCTIONKEYS := 20 ;Number of function keys on the keyboard.
|
||||
DI_KBD_NUMBEROFINDICATORS := 24 ;Number of LED indicators on the keyboard.
|
||||
DI_KBD_NUMBEROFKEYSTOTAL := 28 ;Total number of keys on the keyboard.
|
||||
|
||||
DI_HID_VENDORID := 8 ;Vendor ID for the HID.
|
||||
DI_HID_PRODUCTID := 12 ;Product ID for the HID.
|
||||
DI_HID_VERSIONNUMBER := 16 ;Version number for the HID.
|
||||
DI_HID_USAGEPAGE := 20 | 0x0100 ;Top-level collection Usage Page for the device.
|
||||
DI_HID_USAGE := 22 | 0x0100 ;Top-level collection Usage for the device.
|
||||
;________________________________________
|
||||
;Flags you can use in AHKHID_GetInputInfo
|
||||
;http://msdn.microsoft.com/en-us/library/ms645562
|
||||
II_DEVTYPE := 0 ;Type of the device generating the raw input data. See RIM_ constants.
|
||||
II_DEVHANDLE := 8 ;Handle to the device generating the raw input data.
|
||||
|
||||
II_MSE_FLAGS := (08+A_PtrSize*2) | 0x0100 ;Mouse state. This member can be any reasonable combination of the
|
||||
;following values -> see MOUSE constants.
|
||||
II_MSE_BUTTONFLAGS := (12+A_PtrSize*2) | 0x0100 ;Transition state of the mouse buttons. This member can be one or more of
|
||||
;the following values -> see RI_MOUSE constants.
|
||||
II_MSE_BUTTONDATA := (14+A_PtrSize*2) | 0x1100 ;If usButtonFlags is RI_MOUSE_WHEEL, this member is a signed value that
|
||||
;specifies the wheel delta.
|
||||
II_MSE_RAWBUTTONS := (16+A_PtrSize*2) ;Raw state of the mouse buttons.
|
||||
II_MSE_LASTX := (20+A_PtrSize*2) | 0x1000 ;Motion in the X direction. This is signed relative motion or absolute
|
||||
;motion, depending on the value of usFlags.
|
||||
II_MSE_LASTY := (24+A_PtrSize*2) | 0x1000 ;Motion in the Y direction. This is signed relative motion or absolute
|
||||
;motion, depending on the value of usFlags.
|
||||
II_MSE_EXTRAINFO := (28+A_PtrSize*2) ;Device-specific additional information for the event.
|
||||
|
||||
II_KBD_MAKECODE := (08+A_PtrSize*2) | 0x0100 ;Scan code from the key depression. The scan code for keyboard overrun is
|
||||
;KEYBOARD_OVERRUN_MAKE_CODE.
|
||||
II_KBD_FLAGS := (10+A_PtrSize*2) | 0x0100 ;Flags for scan code information. It can be one or more of the following
|
||||
;values -> see RI_KEY constants.
|
||||
II_KBD_VKEY := (14+A_PtrSize*2) | 0x0100 ;Microsoft Windows message compatible virtual-key code.
|
||||
II_KBD_MSG := (16+A_PtrSize*2) ;Corresponding window message, for example WM_KEYDOWN, WM_SYSKEYDOWN, and
|
||||
;so forth.
|
||||
II_KBD_EXTRAINFO := (20+A_PtrSize*2) ;Device-specific additional information for the event.
|
||||
|
||||
II_HID_SIZE := (08+A_PtrSize*2) ;Size, in bytes, of each HID input in bRawData.
|
||||
II_HID_COUNT := (12+A_PtrSize*2) ;Number of HID inputs in bRawData.
|
||||
|
||||
;DO NOT USE WITH AHKHID_GetInputInfo. Use AHKHID_GetInputData instead to retrieve the raw data.
|
||||
II_HID_DATA := (16+A_PtrSize*2) ;Raw input data as an array of bytes.
|
||||
;__________________________________________________________________________________
|
||||
;Device type values returned by AHKHID_GetDevType as well as DI_DEVTYPE and II_DEVTYPE
|
||||
;http://msdn.microsoft.com/en-us/library/ms645568
|
||||
RIM_TYPEMOUSE := 0 ;The device is a mouse.
|
||||
RIM_TYPEKEYBOARD := 1 ;The device is a keyboard.
|
||||
RIM_TYPEHID := 2 ;The device is an Human Interface Device (HID) that is not a keyboard and not a mouse.
|
||||
;_______________________________________________________________________________________________
|
||||
;Different flags for RAWINPUTDEVICE structure (to be used with AHKHID_AddRegister and AHKHID_Register)
|
||||
;http://msdn.microsoft.com/en-us/library/ms645565
|
||||
RIDEV_REMOVE := 0x00000001 ;If set, this removes the top level collection from the inclusion list. This tells the
|
||||
;operating system to stop reading from a device which matches the top level collection.
|
||||
RIDEV_EXCLUDE := 0x00000010 ;If set, this specifies the top level collections to exclude when reading a complete
|
||||
;usage page. This flag only affects a TLC whose usage page is already specified with
|
||||
;RIDEV_PAGEONLY.
|
||||
RIDEV_PAGEONLY := 0x00000020 ;If set, this specifies all devices whose top level collection is from the specified
|
||||
;usUsagePage. Note that usUsage must be zero. To exclude a particular top level
|
||||
;collection, use RIDEV_EXCLUDE.
|
||||
RIDEV_NOLEGACY := 0x00000030 ;If set, this prevents any devices specified by usUsagePage or usUsage from generating
|
||||
;legacy messages. This is only for the mouse and keyboard. See Remarks.
|
||||
RIDEV_INPUTSINK := 0x00000100 ;If set, this enables the caller to receive the input even when the caller is not in
|
||||
;the foreground. Note that hwndTarget must be specified.
|
||||
RIDEV_CAPTUREMOUSE := 0x00000200 ;If set, the mouse button click does not activate the other window.
|
||||
RIDEV_NOHOTKEYS := 0x00000200 ;If set, the application-defined keyboard device hotkeys are not handled. However, the
|
||||
;system hotkeys; for example, ALT+TAB and CTRL+ALT+DEL, are still handled. By default,
|
||||
;all keyboard hotkeys are handled. RIDEV_NOHOTKEYS can be specified even if
|
||||
;RIDEV_NOLEGACY is not specified and hwndTarget is NULL.
|
||||
RIDEV_APPKEYS := 0x00000400 ;Microsoft Windows XP Service Pack 1 (SP1): If set, the application command keys are
|
||||
;handled. RIDEV_APPKEYS can be specified only if RIDEV_NOLEGACY is specified for a
|
||||
;keyboard device.
|
||||
RIDEV_EXINPUTSINK := 0x00001000 ;Vista and later only: If set, this enables the caller to receive input in the
|
||||
;background only if the foreground application does not process it. In other words, if
|
||||
;the foreground application is not registered for raw input, then the background
|
||||
;application that is registered will receive the input.
|
||||
RIDEV_DEVNOTIFY := 0x00002000 ;Vista and later only: If set, this enables the caller to receive WM_INPUT_DEVICE_CHANGE
|
||||
;notifications for device arrival and device removal.
|
||||
;__________________________________________________
|
||||
;Different values of wParam in the WM_INPUT message
|
||||
;http://msdn.microsoft.com/en-us/library/ms645590
|
||||
RIM_INPUT := 0 ;Input occurred while the application was in the foreground. The application must call
|
||||
;DefWindowProc so the system can perform cleanup.
|
||||
RIM_INPUTSINK := 1 ;Input occurred while the application was not in the foreground. The application must call
|
||||
;DefWindowProc so the system can perform the cleanup.
|
||||
;__________________________________
|
||||
;Flags for GetRawInputData API call
|
||||
;http://msdn.microsoft.com/en-us/library/ms645596
|
||||
RID_INPUT := 0x10000003 ;Get the raw data from the RAWINPUT structure.
|
||||
RID_HEADER := 0x10000005 ;Get the header information from the RAWINPUT structure.
|
||||
;_____________________________________
|
||||
;Flags for RAWMOUSE (part of RAWINPUT)
|
||||
;http://msdn.microsoft.com/en-us/library/ms645578
|
||||
|
||||
;Flags for the II_MSE_FLAGS member
|
||||
MOUSE_MOVE_RELATIVE := 0 ;Mouse movement data is relative to the last mouse position.
|
||||
MOUSE_MOVE_ABSOLUTE := 1 ;Mouse movement data is based on absolute position.
|
||||
MOUSE_VIRTUAL_DESKTOP := 0x02 ;Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system)
|
||||
MOUSE_ATTRIBUTES_CHANGED := 0x04 ;Mouse attributes changed; application needs to query the mouse attributes.
|
||||
|
||||
;Flags for the II_MSE_BUTTONFLAGS member
|
||||
RI_MOUSE_LEFT_BUTTON_DOWN := 0x0001 ;Self-explanatory
|
||||
RI_MOUSE_LEFT_BUTTON_UP := 0x0002 ;Self-explanatory
|
||||
RI_MOUSE_RIGHT_BUTTON_DOWN := 0x0004 ;Self-explanatory
|
||||
RI_MOUSE_RIGHT_BUTTON_UP := 0x0008 ;Self-explanatory
|
||||
RI_MOUSE_MIDDLE_BUTTON_DOWN := 0x0010 ;Self-explanatory
|
||||
RI_MOUSE_MIDDLE_BUTTON_UP := 0x0020 ;Self-explanatory
|
||||
RI_MOUSE_BUTTON_4_DOWN := 0x0040 ;XBUTTON1 changed to down.
|
||||
RI_MOUSE_BUTTON_4_UP := 0x0080 ;XBUTTON1 changed to up.
|
||||
RI_MOUSE_BUTTON_5_DOWN := 0x0100 ;XBUTTON2 changed to down.
|
||||
RI_MOUSE_BUTTON_5_UP := 0x0200 ;XBUTTON2 changed to up.
|
||||
RI_MOUSE_WHEEL := 0x0400 ;Raw input comes from a mouse wheel. The wheel delta is stored in usButtonData.
|
||||
;____________________________________________
|
||||
;Flags for the RAWKEYBOARD (part of RAWINPUT)
|
||||
;http://msdn.microsoft.com/en-us/library/ms645575
|
||||
|
||||
;Flag for the II_KBD_MAKECODE member in the event of a keyboard overrun
|
||||
KEYBOARD_OVERRUN_MAKE_CODE := 0xFF
|
||||
|
||||
;Flags for the II_KBD_FLAGS member
|
||||
RI_KEY_MAKE := 0
|
||||
RI_KEY_BREAK := 1
|
||||
RI_KEY_E0 := 2
|
||||
RI_KEY_E1 := 4
|
||||
RI_KEY_TERMSRV_SET_LED := 8
|
||||
RI_KEY_TERMSRV_SHADOW := 0x10
|
||||
;____________________________________
|
||||
;AHKHID FUNCTIONS
|
||||
|
||||
If Not AHKHID_Included
|
||||
Return
|
||||
|
||||
AHKHID_UseConstants() {
|
||||
Global ;To make the constants global
|
||||
AHKHID_Included := False
|
||||
Gosub, AHKHID_SetConstants
|
||||
}
|
||||
|
||||
AHKHID_Initialize(bRefresh = False) {
|
||||
Static uHIDList, bInitialized := False
|
||||
|
||||
If bInitialized And Not bRefresh
|
||||
Return &uHIDList
|
||||
|
||||
;Get the device count
|
||||
r := DllCall("GetRawInputDeviceList", "Ptr", 0, "UInt*", iCount, "UInt", A_PtrSize * 2)
|
||||
|
||||
;Check for error
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputDeviceList call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
|
||||
;Prep var
|
||||
VarSetCapacity(uHIDList, iCount * (A_PtrSize * 2))
|
||||
r := DllCall("GetRawInputDeviceList", "Ptr", &uHIDList, "UInt*", iCount, "UInt", A_PtrSize * 2)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputDeviceList call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
|
||||
bInitialized := True
|
||||
Return &uHIDList
|
||||
}
|
||||
|
||||
AHKHID_GetDevCount() {
|
||||
|
||||
;Get the device count
|
||||
r := DllCall("GetRawInputDeviceList", "Ptr", 0, "UInt*", iCount, "UInt", A_PtrSize * 2)
|
||||
|
||||
;Check for error
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputDeviceList call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
} Else Return iCount
|
||||
}
|
||||
|
||||
AHKHID_GetDevHandle(i) {
|
||||
Return NumGet(AHKHID_Initialize(), (i - 1) * (A_PtrSize * 2))
|
||||
}
|
||||
|
||||
AHKHID_GetDevIndex(Handle) {
|
||||
Loop % AHKHID_GetDevCount()
|
||||
If (NumGet(AHKHID_Initialize(), (A_Index - 1) * (A_PtrSize * 2)) = Handle)
|
||||
Return A_Index
|
||||
Return 0
|
||||
}
|
||||
|
||||
AHKHID_GetDevType(i, IsHandle = False) {
|
||||
Return Not IsHandle ? NumGet(AHKHID_Initialize(), ((i - 1) * (A_PtrSize * 2)) + A_PtrSize, "UInt")
|
||||
: NumGet(AHKHID_Initialize(), ((AHKHID_GetDevIndex(i) - 1) * (A_PtrSize * 2)) + A_PtrSize, "UInt")
|
||||
}
|
||||
|
||||
AHKHID_GetDevName(i, IsHandle = False) {
|
||||
|
||||
;Get index if i is handle
|
||||
h := IsHandle ? i : AHKHID_GetDevHandle(i)
|
||||
|
||||
;Get device name length. RIDI_DEVICENAME
|
||||
r := DllCall("GetRawInputDeviceInfo", "Ptr", h, "UInt", 0x20000007, "Ptr", 0, "UInt*", iLength)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputDeviceInfo call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return ""
|
||||
}
|
||||
|
||||
;Get device name.
|
||||
VarSetCapacity(s, (iLength + 1) * 2) ;RIDI_DEVICENAME
|
||||
r := DllCall("GetRawInputDeviceInfo", "Ptr", h, "UInt", 0x20000007, "Str", s, "UInt*", iLength)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputDeviceInfo call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return ""
|
||||
}
|
||||
|
||||
Return s
|
||||
}
|
||||
|
||||
AHKHID_GetDevInfo(i, Flag, IsHandle = False) {
|
||||
Static uInfo, iLastHandle := 0
|
||||
|
||||
;Get index if i is handle
|
||||
h := IsHandle ? i : AHKHID_GetDevHandle(i)
|
||||
|
||||
;Check if the handle changed
|
||||
If (h = iLastHandle) ;It's the same device. No need to call again
|
||||
Return NumGet(uInfo, Flag, AHKHID_NumIsShort(Flag) ? "UShort" : "UInt")
|
||||
Else {
|
||||
|
||||
;Get device info buffer size. RIDI_DEVICEINFO
|
||||
r := DllCall("GetRawInputDeviceInfo", "Ptr", h, "UInt", 0x2000000b, "Ptr", 0, "UInt*", iLength)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputDeviceInfo call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
|
||||
;Get device info
|
||||
VarSetCapacity(uInfo, iLength)
|
||||
NumPut(iLength, uInfo, 0, "UInt") ;Put length in struct RIDI_DEVICEINFO
|
||||
r := DllCall("GetRawInputDeviceInfo", "Ptr", h, "UInt", 0x2000000b, "Ptr", &uInfo, "UInt*", iLength)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputDeviceInfo call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
|
||||
;Successful. Keep handle.
|
||||
iLastHandle := h
|
||||
|
||||
;Retrieve data
|
||||
Return NumGet(uInfo, Flag, AHKHID_NumIsShort(Flag) ? "UShort" : "UInt")
|
||||
}
|
||||
|
||||
Return 0
|
||||
}
|
||||
|
||||
AHKHID_AddRegister(UsagePage = False, Usage = False, Handle = False, Flags = 0) {
|
||||
Static uDev, iIndex := 0, iCount := 0
|
||||
|
||||
;Check if we just want the address
|
||||
If Not (UsagePage Or Usage Or Handle Or Flags)
|
||||
Return &uDev
|
||||
;Check if we just want the count
|
||||
Else If (UsagePage = "Count")
|
||||
Return iCount
|
||||
;Check if we're dimensioning the struct
|
||||
Else If UsagePage And Not (Usage Or Handle Or Flags) {
|
||||
iCount := UsagePage
|
||||
iIndex := 0
|
||||
VarSetCapacity(uDev, iCount * (8 + A_PtrSize))
|
||||
Return &uDev
|
||||
}
|
||||
|
||||
;Check if there's space before adding data to struct
|
||||
If (iIndex = iCount)
|
||||
Return -1 ;Full capacity
|
||||
|
||||
;Check if hwnd needs to be null. RIDEV_REMOVE, RIDEV_EXCLUDE
|
||||
Handle := ((Flags & 0x00000001) Or (Flags & 0x00000010)) ? 0 : Handle
|
||||
|
||||
;Put in struct
|
||||
NumPut(UsagePage, uDev, (iIndex * (8 + A_PtrSize)) + 0, "UShort")
|
||||
NumPut(Usage, uDev, (iIndex * (8 + A_PtrSize)) + 2, "UShort")
|
||||
NumPut(Flags, uDev, (iIndex * (8 + A_PtrSize)) + 4, "UInt")
|
||||
NumPut(Handle, uDev, (iIndex * (8 + A_PtrSize)) + 8, "Ptr")
|
||||
|
||||
;Move to next slot
|
||||
iIndex += 1
|
||||
|
||||
Return &uDev
|
||||
}
|
||||
|
||||
AHKHID_Register(UsagePage = False, Usage = False, Handle = False, Flags = 0) {
|
||||
|
||||
;Check if we're using the AddRegister array or only a single struct
|
||||
If Not (UsagePage Or Usage Or Handle Or Flags) {
|
||||
|
||||
;Call
|
||||
r := DllCall("RegisterRawInputDevices", "Ptr", AHKHID_AddRegister(), "UInt", AHKHID_AddRegister("Count"), "UInt", 8 + A_PtrSize)
|
||||
|
||||
;Check for error
|
||||
If Not r {
|
||||
ErrorLevel = RegisterRawInputDevices call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
|
||||
;Build struct and call
|
||||
} Else {
|
||||
|
||||
;Prep var
|
||||
VarSetCapacity(uDev, (8 + A_PtrSize), 0)
|
||||
|
||||
;Check if hwnd needs to be null. RIDEV_REMOVE, RIDEV_EXCLUDE
|
||||
Handle := ((Flags & 0x00000001) Or (Flags & 0x00000010)) ? 0 : Handle
|
||||
|
||||
NumPut(UsagePage, uDev, 0, "UShort")
|
||||
NumPut(Usage, uDev, 2, "UShort")
|
||||
NumPut(Flags, uDev, 4, "UInt")
|
||||
NumPut(Handle, uDev, 8, "Ptr")
|
||||
|
||||
;Call
|
||||
r := DllCall("RegisterRawInputDevices", "Ptr", &uDev, "UInt", 1, "UInt", 8 + A_PtrSize)
|
||||
|
||||
;Check for error
|
||||
If Not r Or ErrorLevel {
|
||||
ErrorLevel = RegisterRawInputDevices call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
}
|
||||
|
||||
Return 0
|
||||
}
|
||||
|
||||
AHKHID_GetRegisteredDevs(ByRef uDev) {
|
||||
|
||||
;Get length
|
||||
VarSetCapacity(iCount, 4, 0)
|
||||
r := DllCall("GetRegisteredRawInputDevices", "Ptr", 0, "UInt*", iCount, "UInt", 8 + A_PtrSize)
|
||||
If ErrorLevel {
|
||||
ErrorLevel = GetRegisteredRawInputDevices call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
|
||||
If (iCount > 0) {
|
||||
|
||||
;Prep var
|
||||
VarSetCapacity(uDev, iCount * (8 + A_PtrSize))
|
||||
|
||||
;Call
|
||||
r := DllCall("GetRegisteredRawInputDevices", "Ptr", &uDev, "UInt*", iCount, "UInt", 8 + A_PtrSize)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRegisteredRawInputDevices call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
}
|
||||
|
||||
Return iCount
|
||||
}
|
||||
|
||||
AHKHID_GetInputInfo(InputHandle, Flag) {
|
||||
Static uRawInput, iLastHandle := 0
|
||||
|
||||
;Check if it's the same handle
|
||||
If (InputHandle = iLastHandle) ;We can retrieve the data without having to call again
|
||||
Return NumGet(uRawInput, Flag, AHKHID_NumIsShort(Flag) ? (AHKHID_NumIsSigned(Flag) ? "Short" : "UShort") : (AHKHID_NumIsSigned(Flag) ? "Int" : (Flag = 8 ? "Ptr" : "UInt")))
|
||||
Else { ;We need to get a fresh copy
|
||||
|
||||
;Get raw data size RID_INPUT
|
||||
r := DllCall("GetRawInputData", "UInt", InputHandle, "UInt", 0x10000003, "Ptr", 0, "UInt*", iSize, "UInt", 8 + A_PtrSize * 2)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputData call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
|
||||
;Prep var
|
||||
VarSetCapacity(uRawInput, iSize)
|
||||
|
||||
;Get raw data RID_INPUT
|
||||
r := DllCall("GetRawInputData", "UInt", InputHandle, "UInt", 0x10000003, "Ptr", &uRawInput, "UInt*", iSize, "UInt", 8 + A_PtrSize * 2)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputData call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
} Else If (r <> iSize) {
|
||||
ErrorLevel = GetRawInputData did not return the correct size.`nSize returned: %r%`nSize allocated: %iSize%
|
||||
Return -1
|
||||
}
|
||||
|
||||
;Keep handle reference of current uRawInput
|
||||
iLastHandle := InputHandle
|
||||
|
||||
;Retrieve data
|
||||
Return NumGet(uRawInput, Flag, AHKHID_NumIsShort(Flag) ? (AHKHID_NumIsSigned(Flag) ? "Short" : "UShort") : (AHKHID_NumIsSigned(Flag) ? "Int" : (Flag = 8 ? "Ptr" : "UInt")))
|
||||
}
|
||||
|
||||
Return 0
|
||||
}
|
||||
|
||||
AHKHID_GetInputData(InputHandle, ByRef uData) {
|
||||
|
||||
;Get raw data size RID_INPUT
|
||||
r := DllCall("GetRawInputData", "UInt", InputHandle, "UInt", 0x10000003, "Ptr", 0, "UInt*", iSize, "UInt", 8 + A_PtrSize * 2)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputData call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
}
|
||||
|
||||
;Prep var
|
||||
VarSetCapacity(uRawInput, iSize)
|
||||
|
||||
;Get raw data RID_INPUT
|
||||
r := DllCall("GetRawInputData", "UInt", InputHandle, "UInt", 0x10000003, "Ptr", &uRawInput, "UInt*", iSize, "UInt", 8 + A_PtrSize * 2)
|
||||
If (r = -1) Or ErrorLevel {
|
||||
ErrorLevel = GetRawInputData call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
Return -1
|
||||
} Else If (r <> iSize) {
|
||||
ErrorLevel = GetRawInputData did not return the correct size.`nSize returned: %r%`nSize allocated: %iSize%
|
||||
Return -1
|
||||
}
|
||||
|
||||
;Get the size of each HID input and the number of them
|
||||
iSize := NumGet(uRawInput, 8 + A_PtrSize * 2 + 0, "UInt") ;ID_HID_SIZE
|
||||
iCount := NumGet(uRawInput, 8 + A_PtrSize * 2 + 4, "UInt") ;ID_HID_COUNT
|
||||
|
||||
;Allocate memory
|
||||
VarSetCapacity(uData, iSize * iCount)
|
||||
|
||||
;Copy bytes
|
||||
DllCall("RtlMoveMemory", UInt, &uData, UInt, &uRawInput + 8 + A_PtrSize * 2 + 8, UInt, iSize * iCount)
|
||||
|
||||
Return (iSize * iCount)
|
||||
}
|
||||
|
||||
;Internal use only
|
||||
AHKHID_NumIsShort(ByRef Flag) {
|
||||
If (Flag & 0x0100) {
|
||||
Flag ^= 0x0100 ;Remove it
|
||||
Return True
|
||||
} Return False
|
||||
}
|
||||
|
||||
;Internal use only
|
||||
AHKHID_NumIsSigned(ByRef Flag) {
|
||||
If (Flag & 0x1000) {
|
||||
Flag ^= 0x1000 ;Remove it
|
||||
Return True
|
||||
} Return False
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
#SingleInstance Force
|
||||
#Persistent
|
||||
#include AHKHID.ahk
|
||||
|
||||
hArd := HID_Open("2341","003E")
|
||||
while (hLED = -1) {
|
||||
hArd := HID_Open("2341","003E")
|
||||
Sleep, 5000
|
||||
}
|
||||
if 0 < 1 ; The left side of a non-expression if-statement is always the name of a variable.
|
||||
{
|
||||
MsgBox This script requires a parameter
|
||||
ExitApp
|
||||
}
|
||||
|
||||
param := %A_Index%
|
||||
mode := %param% + 16
|
||||
if (mode > 19) or (mode < 16){
|
||||
MsgBox, Incorrect value %mode%
|
||||
ExitApp
|
||||
}
|
||||
changeMode(hArd,mode)
|
||||
HID_Close(hArd)
|
||||
ExitApp
|
||||
|
||||
changeMode(hArd,Num){
|
||||
;MsgBox, sending %Num%
|
||||
TestString = "aa"
|
||||
NumPut(5,TestString,0,"UInt")
|
||||
NumPut(0,TestString,1, "UInt")
|
||||
NumPut(0,TestString,2, "UInt")
|
||||
NumPut(0,TestString,3, "UInt")
|
||||
NumPut(Num,TestString,4, "UInt")
|
||||
;outputdebug teststring %TestString%
|
||||
HID_Write(hArd,TestString,5)
|
||||
}
|
||||
|
||||
;DLL CALLS
|
||||
HID_Open(VID,PID){
|
||||
str = VID_%VID%`&PID_%PID%
|
||||
iCount := AHKHID_GetDevCount()
|
||||
Loop , %icount%
|
||||
{
|
||||
HID0 += 1
|
||||
name := AHKHID_GetDevName(HID0)
|
||||
type := AHKHID_GetDevType(HID0)
|
||||
;outputdebug str to find is %str%
|
||||
if type = 2
|
||||
{
|
||||
if name contains %str%
|
||||
{
|
||||
;outputdebug found %VID%:%PID% under name: %name%
|
||||
return HandleFromName(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
;outputdebug (%VID%:%PID% not found)
|
||||
return -1
|
||||
}
|
||||
|
||||
HandleFromName(FileName){
|
||||
GENERIC_READ = 0x80000000 ; Open the file for reading rather than writing.
|
||||
GENERIC_WRITE = 0x40000000
|
||||
OPEN_EXISTING = 3 ; This mode indicates that the file to be opened must already exist.
|
||||
FILE_SHARE_READ = 0x1 ; This and the next are whether other processes can open the file while we have it open.
|
||||
FILE_SHARE_WRITE = 0x2
|
||||
;outputdebug Calling Createfile on %FileName%
|
||||
hFile := DllCall("CreateFile", Str, FileName, UInt, GENERIC_READ|GENERIC_WRITE, UInt, FILE_SHARE_READ|FILE_SHARE_WRITE, Ptr, 0, UInt, OPEN_EXISTING, UInt, 0, Ptr, 0)
|
||||
If (hFile = -1) Or ErrorLevel
|
||||
{
|
||||
ErrorLevel = CreateFile call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
outputdebug (%A_LineNumber%) %errorlevel%
|
||||
Return -1
|
||||
}
|
||||
;outputdebug file handle %hFile%
|
||||
return hFile
|
||||
}
|
||||
|
||||
HID_Write(handle,data,len=-1){
|
||||
BytesToWrite := (len>0) ? len : VarSetCapacity(data, -1)
|
||||
;outputdebug length %BytesToWrite%
|
||||
r := DllCall("WriteFile", Ptr, handle, Str, data, UInt, BytesToWrite, UIntP, BytesActuallyWritten, Ptr, 0)
|
||||
If (r = -1) Or ErrorLevel
|
||||
{
|
||||
ErrorLevel = WriteFile call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
|
||||
outputdebug (%A_LineNumber%) %errorlevel%
|
||||
Return -1
|
||||
}
|
||||
;outputdebug writefile %r%
|
||||
return BytesActuallyWritten
|
||||
}
|
||||
|
||||
HID_Close(handle){
|
||||
DllCall("CloseHandle", Ptr, handle) ; Close the file.
|
||||
}
|
||||
Reference in New Issue
Block a user