 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
shaun Guest
|
Posted: Tue Jan 06, 2009 11:16 pm Post subject: HID/Extended input devices (MS Natural Keyboard 4000 etc.) |
|
|
Hi All,
The Microsoft Natural Keyboard 4000 has a "Zoom" slider in the centre of the keyboard that is kind of useless that I wanted to change to be a scroll slider. Unfortunately, it's not detected as a key by AutoHotkey normally. This is because the keyboard registers as a keyboard (which gets most of the input) AND a different HID device that receives input from the special keys.
Many other USB devices behave this way (e.g remote controls, mice with extended features). There have been a number of posts on this and Micha has posted a DLL to make this easier in AutoHotKey, but here's my stab at it.
First a script that lists all of the available raw input devices and can capture and decode all of the input. This is useful to work out what messages the device sends as well as the "Usage" and "Usage Page" of the top level collection of the HID device:
| Code: |
; List all of the "Raw Input" devices available for use and allow
; capture of output
;
; There may be more than one 'raw' device per device actually attached
; to the system. This is because these devices generally represent
; "HID Collections", and there may be more than one HID collection per
; USB device. For example, the Natural Keyboard 4000 supports a normal
; keyboard HID collection, plus an additional HID collection that can
; be used for the zoom slider and other important buttons
; Replace any previous instance
#SingleInstance force
DetectHiddenWindows, on
OnMessage(0x00FF, "InputMessage")
SizeofRawInputDeviceList := 8
SizeofRidDeviceInfo := 32
SizeofRawInputDevice := 12
RIM_TYPEMOUSE := 0
RIM_TYPEKEYBOARD := 1
RIM_TYPEHID := 2
RIDI_DEVICENAME := 0x20000007
RIDI_DEVICEINFO := 0x2000000b
RIDEV_INPUTSINK := 0x00000100
RID_INPUT := 0x10000003
DoCapture := 0
Gui, Add, Edit, HScroll w460 h300 vInfoOut -Wrap ReadOnly HwndInfoHwnd
Gui, Add, Edit, HScroll w460 h300 vEditOut -Wrap ReadOnly HwndEditHwnd
Gui, Add, Button, Default gCapture vCaptureButton w150, &Capture
Gui, Show, , HIDList
HWND := WinExist("HIDList")
Res := DllCall("GetRawInputDeviceList", UInt, 0, "UInt *", Count, UInt, SizeofRawInputDeviceList)
InfoOutput("There are " . Count . " raw input devices`r`n`r`n")
VarSetCapacity(RawInputList, SizeofRawInputDeviceList * Count)
Res := DllCall("GetRawInputDeviceList", UInt, &RawInputList, "UInt *", Count, UInt, SizeofRawInputDeviceList)
MouseRegistered := 0
KeyboardRegistered := 0
Loop %Count% {
Handle := NumGet(RawInputList, (A_Index - 1) * SizeofRawInputDeviceList)
Type := NumGet(RawInputList, (A_Index - 1) * SizeofRawInputDeviceList + 4)
if (Type = RIM_TYPEMOUSE)
TypeName := "RIM_TYPEMOUSE"
else if (Type = RIM_TYPEKEYBOARD)
TypeName := "RIM_TYPEKEYBOARD"
else if (Type = RIM_TYPEHID)
TypeName := "RIM_TYPEHID"
else
TypeName := "RIM_OTHER"
InfoOutput("Device " . A_Index . ": Handle " . Handle . " Type " . Type . " (" . TypeName . ") ")
Res := DllCall("GetRawInputDeviceInfo", UInt, Handle, UInt, RIDI_DEVICENAME, UInt, 0, "UInt *", Length)
VarSetCapacity(Name, Length + 2)
Res := DllCall("GetRawInputDeviceInfo", UInt, Handle, UInt, RIDI_DEVICENAME, "Str", Name, "UInt *", Length)
InfoOutput("Name " . Name . "`r`n")
VarSetCapacity(Info, SizeofRidDeviceInfo)
NumPut(SizeofRidDeviceInfo, Info, 0)
Length := SizeofRidDeviceInfo
Res := DllCall("GetRawInputDeviceInfo", UInt, Handle, UInt, RIDI_DEVICEINFO, UInt, &Info, "UInt *", SizeofRidDeviceInfo)
if (Type = RIM_TYPEMOUSE)
InfoOutput("Buttons " . NumGet(Info, 4 * 3) . " Sample rate " . NumGet(Info, 4 * 4) . "`r`n")
else if (Type = RIM_TYPEKEYBOARD)
InfoOutput("Mode " . NumGet(Info, 4 * 4) . " Function keys " . NumGet(Info, 4 * 5) . "`r`n")
else if (Type = RIM_TYPEHID)
{
InfoOutput("Vendor " . NumGet(Info, 4 * 2) . " Product " . NumGet(Info, 4 * 3) . " Version " . NumGet(Info, 4 * 4) . " ")
UsagePage := NumGet(Info, (4 * 5), "UShort")
Usage := NumGet(Info, (4 * 5) + 2, "UShort")
InfoOutput("Usage " . Usage . " Usage Page " . UsagePage . "`r`n")
}
; Keyboards are always Usage 6, Usage Page 1, Mice are Usage 2, Usage Page 1,
; HID devices specify their top level collection in the info block
VarSetCapacity(RawDevice, SizeofRawInputDevice)
NumPut(RIDEV_INPUTSINK, RawDevice, 4)
NumPut(HWND, RawDevice, 8)
DoRegister := 0
if (Type = RIM_TYPEMOUSE && MouseRegistered = 0)
{
DoRegister := 1
; Mice are Usage 2, Usage Page 1
NumPut(1, RawDevice, 0, "UShort")
NumPut(2, RawDevice, 2, "UShort")
MouseRegistered := 1
}
else if (Type = RIM_TYPEKEYBOARD && KeyboardRegistered = 0)
{
DoRegister := 1
; Keyboards are always Usage 6, Usage Page 1
NumPut(1, RawDevice, 0, "UShort")
NumPut(6, RawDevice, 2, "UShort")
KeyboardRegistered := 1
}
else if (Type = RIM_TYPEHID)
{
DoRegister := 1
NumPut(UsagePage, RawDevice, 0, "UShort")
NumPut(Usage, RawDevice, 2, "UShort")
}
if (DoRegister)
{
Res := DllCall("RegisterRawInputDevices", "UInt", &RawDevice, UInt, 1, UInt, SizeofRawInputDevice)
if (Res = 0)
InfoOutput("Failed to register for this device!`r`n")
else
InfoOutput("Registered for this device`r`n")
}
}
Count := 1
InputMessage(wParam, lParam, msg, hwnd)
{
global DoCapture
global RIM_TYPEMOUSE, RIM_TYPEKEYBOARD, RIM_TYPEHID
global RID_INPUT
if (DoCapture = 0)
return
Res := DllCall("GetRawInputData", UInt, lParam, UInt, RID_INPUT, UInt, 0, "UInt *", Size, UInt, 16)
VarSetCapacity(Buffer, Size)
Res := DllCall("GetRawInputData", UInt, lParam, UInt, RID_INPUT, UInt, &Buffer, "UInt *", Size, UInt, 16)
; AppendOutput(Mem2Hex(&Buffer, Size))
Type := NumGet(Buffer, 0 * 4)
Size := NumGet(Buffer, 1 * 4)
Handle := NumGet(Buffer, 2 * 4)
;AppendOutput("Got Input with " . Res . " size " . Size . " Type " . Type . " Handle " . Handle . "`r`n")
if (Type = RIM_TYPEMOUSE)
{
LastX := NumGet(Buffer, (16 + (4 * 3)), "Int")
LastY := NumGet(Buffer, (16 + (4 * 4)), "Int")
AppendOutput("HND " . Handle . " MOUSE LastX " . LastX . " LastY " . LastY . "`r`n")
}
else if (Type = RIM_TYPEKEYBOARD)
{
ScanCode := NumGet(Buffer, (16 + 0), "UShort")
VKey := NumGet(Buffer, (16 + 6), "UShort")
Message := NumGet(Buffer, (16 + 8))
AppendOutput("HND " . Handle . " KBD ScanCode " . ScanCode . " VKey " . VKey . " Msg " . Message . "`r`n")
}
else if (Type = RIM_TYPEHID)
{
SizeHid := NumGet(Buffer, (16 + 0))
InputCount := NumGet(Buffer, (16 + 4))
AppendOutput("HND " . Handle . " HID Size " . SizeHid . " Count " . InputCount . " Ptr " . &Buffer . "`r`n")
Loop %InputCount% {
Addr := &Buffer + 24 + ((A_Index - 1) * SizeHid)
BAddr := &Buffer
;MsgBox, BAddr %BAddr% Addr %Addr%
AppendOutput("Input " . Mem2Hex(Addr, SizeHid) . "`r`n")
}
}
else
{
AppendOutput("HND " . Handle . " Unknown Type " . Type)
}
return
}
return
Exit
Capture:
{
if (DoCapture = 0)
{
GuiControl, , CaptureButton, Stop &Capture
DoCapture := 1
}
else
{
GuiControl, , CaptureButton, &Capture
DoCapture := 0
}
return
}
GuiClose:
ExitApp
Mem2Hex( pointer, len )
{
A_FI := A_FormatInteger
SetFormat, Integer, Hex
Loop, %len% {
Hex := *Pointer+0
StringReplace, Hex, Hex, 0x, 0x0
StringRight Hex, Hex, 2
hexDump := hexDump . hex
Pointer ++
}
SetFormat, Integer, %A_FI%
StringUpper, hexDump, hexDump
Return hexDump
}
InfoOutput(Text)
{
global InfoHwnd
GuiControlGet, InfoOut
NewText := InfoOut . Text
GuiControl, , InfoOut, %NewText%
return
}
AppendOutput(Text)
{
global EditHwnd
GuiControlGet, EditOut
NewText := EditOut . Text
GuiControl, , EditOut, %NewText%
; WM_VSCROLL (0x115), SB_BOTTOM (7)
;MsgBox, %EditHwnd%
SendMessage, 0x115, 0x0000007, 0, , ahk_id %EditHwnd%
return
}
|
For example, the Natural keyboard 4000 shows up as:
Device 1: Handle 196713 Type 2 (RIM_TYPEHID) Name \??\HID#Vid_045e&Pid_00db&MI_01#8&34dbdc06&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
Vendor 1118 Product 219 Version 371 Usage 1 Usage Page 12
Here's a script that converts the zoom slider to be a scroll slider. It can easily be converted to accept input from any HID device:
| Code: |
; Capture input from the "Zoom" slider on the Natural Keyboard 4000
; and use it to scroll up and scroll down
; The HID top level collection for the Natural Keyboard 4000 is:
; Usage 1
; Usage Page 12
#NoTrayIcon
; Replace any previous instance
#SingleInstance force
DetectHiddenWindows, on
OnMessage(0x00FF, "InputMessage")
SizeofRawInputDeviceList := 8
SizeofRidDeviceInfo := 32
RIM_TYPEMOUSE := 0
RIM_TYPEKEYBOARD := 1
RIM_TYPEHID := 2
RIDI_DEVICENAME := 0x20000007
RIDI_DEVICEINFO := 0x2000000b
RIDEV_INPUTSINK := 0x00000100
RID_INPUT := 0x10000003
Usage := 1
UsagePage := 12
Gui, Show, Hide, NaturalCapture
HWND := WinExist("NaturalCapture")
; Keyboards are always Usage 6, Usage Page 1, Mice are Usage 2, Usage Page 1,
; HID devices specify their top level collection in the info block
VarSetCapacity(RawDevice, 12)
NumPut(RIDEV_INPUTSINK, RawDevice, 4)
NumPut(HWND, RawDevice, 8)
NumPut(UsagePage, RawDevice, 0, "UShort")
NumPut(Usage, RawDevice, 2, "UShort")
Res := DllCall("RegisterRawInputDevices", "UInt", &RawDevice, UInt, 1, UInt, 12)
if (Res = 0)
MsgBox, Failed to register for Natural Keyboard
InputMessage(wParam, lParam, msg, hwnd)
{
global DoCapture
global RIM_TYPEMOUSE, RIM_TYPEKEYBOARD, RIM_TYPEHID
global RID_INPUT
if (DoCapture = 0)
return
Res := DllCall("GetRawInputData", UInt, lParam, UInt, RID_INPUT, UInt, 0, "UInt *", Size, UInt, 16)
VarSetCapacity(Buffer, Size)
Res := DllCall("GetRawInputData", UInt, lParam, UInt, RID_INPUT, UInt, &Buffer, "UInt *", Size, UInt, 16)
Type := NumGet(Buffer, 0 * 4)
Size := NumGet(Buffer, 1 * 4)
Handle := NumGet(Buffer, 2 * 4)
;AppendOutput("Got Input with " . Res . " size " . Size . " Type " . Type . " Handle " . Handle . "`r`n")
if (Type = RIM_TYPEHID)
{
SizeHid := NumGet(Buffer, (16 + 0))
InputCount := NumGet(Buffer, (16 + 4))
;Debug("HND " . Handle . " HID Size " . SizeHid . " Count " . InputCount . " Ptr " . &Buffer . "`r`n")
Loop %InputCount% {
Addr := &Buffer + 24 + ((A_Index - 1) * SizeHid)
BAddr := &Buffer
;MsgBox, BAddr %BAddr% Addr %Addr%
Input := Mem2Hex(Addr, SizeHid)
;Debug("Input " . Input . "`r`n")
if (IsLabel(Input))
Gosub, %Input%
}
}
return
}
return
Exit
GuiClose:
ExitApp
; 1 = UP, 2 = DOWN
ScrollDir := 0
DoScroll:
ControlGetFocus, fcontrol, A
; WM_VSCROLL = 0x115, SB_LINEUP = 0, SB_LINEDOWN = 1
WinGetClass, ClassName, A
;Debug("Class " . ClassName)
if (InStr(ClassName, "Mozilla"))
{
IsMozilla := 1
}
else
{
IsMozilla := 0
}
Loop 3 {
if (ScrollDir = 1)
{
if (IsMozilla)
SendInput, {Up}
else
SendMessage, 0x115, 0, 0, %fcontrol%, A
}
else
{
if (IsMozilla)
SendInput, {Down}
else
SendMessage, 0x115, 1, 0, %fcontrol%, A
}
}
;Debug("Done")
Return
; Zoom down
012E020000010000:
ScrollDir := 2
GoSub, DoScroll
SetTimer, DoScroll, 80
return
; Zoom up
012D020000010000:
ScrollDir := 1
GoSub, DoScroll
SetTimer, DoScroll, 80
return
; All up
0100000000010000:
ScrollDir := 0
SetTimer, DoScroll, Off
return
Debug(msg)
{
OutputDebug, %msg%
return
}
Mem2Hex( pointer, len )
{
A_FI := A_FormatInteger
SetFormat, Integer, Hex
Loop, %len% {
Hex := *Pointer+0
StringReplace, Hex, Hex, 0x, 0x0
StringRight Hex, Hex, 2
hexDump := hexDump . hex
Pointer ++
}
SetFormat, Integer, %A_FI%
StringUpper, hexDump, hexDump
Return hexDump
}
|
Cheers,
Shaun |
|
| Back to top |
|
 |
John Burgos Guest
|
Posted: Thu Jan 08, 2009 7:58 am Post subject: HID Keyboard |
|
|
Hey, looks you have done a nice jod.... maybe you can help me out, im new with AutoHotkey, but what I want to do is to be able to remap my external USB HID Keyboard keys (but only remapping the external HID, without affecting the keys of the HID keyboard included in my laptop).
I have read the basics and followed some tutorials, but so far I can only remap keys but afecting both keyboards... Is there a way to only chose one keyboard to remap???
Hope you can help me out, since I tryied to understand your code, but it is too advanced for me...
Thanks in advance
John |
|
| Back to top |
|
 |
lilalurl.T32
Joined: 17 May 2007 Posts: 391 Location: Titan
|
Posted: Thu Jan 08, 2009 8:33 am Post subject: |
|
|
Fantastic job Shaun.
First, in case you don't know, there is a simpler approach to changing zoom to scroll, by editing the commands.xml file in the intellitype folder and changing the current value for C139 and C320 to
| Code: | <C319 Type="6" Activator="ScrollUp" />
<C320 Type="6" Activator="ScrollDown" /> |
See there for more details:
http://huddledmasses.org/hacking-the-natural-4000-keyboard/
The second comment (by Scott) is also quite useful to learn how the 4000 works.
Anyway, as far as I know, your script is the only way to remap the "my favorites" key ( 0182010000010000 ) to something.
Same goes for the F-Lock key ( 0100000000020000 and 0100000000030000 ).
So once again, good job.
Edit: Just thought of another application for your script, remapping the numpad additional keys (= ( ) and <-). Here are the results of my test for people interested.
The backspace key behaves as a normal backspace key, so I guess it can't be remapped to something else.
However the three others register as speficic HID keys. Here are the values:
| Code: | ;numpad=
0100006700010000:
msgbox equal
return
;numpad(
010000B600010000:
msgbox (
return
;numpad)
010000B700010000:
msgbox )
return |
________
Box vaporizer
Last edited by lilalurl.T32 on Fri Feb 11, 2011 8:44 pm; edited 1 time in total |
|
| Back to top |
|
 |
j0dan
Joined: 02 Feb 2009 Posts: 11 Location: Abbotsford, BC, Canada
|
Posted: Sat Feb 07, 2009 8:05 am Post subject: |
|
|
Thank-you so much for this!!!
Here are the mappings for all the favorite buttons:
| Code: | ; My Favorites
0182010000010000:
MsgBox My Favorites Button
return
; Favorites 1
0100000000050000:
MsgBox Favorites 1
return
; Favorites 2
0100000000090000:
MsgBox Favorites 2
return
; Favorites 3
0100000000110000:
MsgBox Favorites 3
return
; Favorites 4
0100000000210000:
MsgBox Favorites 4
return
; Favorites 5
0100000000410000:
MsgBox Favorites 5
return
|
Now I just need to find out why the scrolling sometimes gets stuck in Firefox. I would rather it just executed the Mousewheel commands. That way I can just use it when my finger gets tired of mouse wheeling. |
|
| Back to top |
|
 |
..:: Free Radical ::..
Joined: 20 Sep 2006 Posts: 72
|
Posted: Sat Feb 07, 2009 10:22 am Post subject: |
|
|
This is awesome!
Thank you very much Shaun  |
|
| Back to top |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Sun Feb 08, 2009 3:09 pm Post subject: |
|
|
So, those api calls can be used to replace Micha's dll?
If so, that's amazing! |
|
| Back to top |
|
 |
mprost
Joined: 15 Dec 2006 Posts: 4
|
Posted: Fri Feb 13, 2009 10:42 am Post subject: |
|
|
| works great! thank you very much Shaun |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7279 Location: Australia
|
Posted: Sun Feb 15, 2009 3:48 am Post subject: |
|
|
| j0dan wrote: | | Here are the mappings for all the favorite buttons: | I'm not sure if the HID device works the same for the Microsoft Natural Keyboard 4000 as for the Wireless Media Desktop 1000 (keyboard), but looking at the "codes" in this thread, I'd say there's a strong possibility it does. If it does, those mappings will only work if F-lock is on and certain other keys aren't being held.
| Quote: | | Now I just need to find out why the scrolling sometimes gets stuck in Firefox. | Might also be related to this.
When I first tried the script with my (new) Wireless Media Desktop 1000, I noticed the codes differ when:
- F-lock is enabled/disabled.
- One or more extra keys [1] to [5] are held down.
- One or more standard modifier keys are held down.
After a bit of experimentation, I've found the format seems to be:
- Byte 0: 0x01, 0x04 or 0x05. Only input packets beginning with 0x01 seem to be meaningful.
- Byte 1-2: Identifies any of the special keys, including standard media keys handled by Windows, but excluding [1] to [5] and F-lock. 0x0000 if a key was released (unfortunately I can't detect which one).
- Byte 3-4: Unknown.
- Byte 5: Bitfield representing the state of a number of keys. In low to high bit order: F-lock ON/OFF, F-lock pressed (not updated immediately on release), [1] .. [5], unknown.
- Byte 6: Unknown.
- Byte 7: Modifier key state. In low to high bit order: LCtrl, LShift, LAlt, LWin, RCtrl, RShift, RAlt.
Based on shaun's script:
| Code: | ; Capture various button presses from Wireless Media Desktop 1000 (Keyboard).
; The HID top level collection for the Wireless Media Desktop 1000 (Keyboard) is:
; Usage 1
; Usage Page 12
#NoTrayIcon
; Replace any previous instance
#SingleInstance force
DetectHiddenWindows, on
OnMessage(0x00FF, "InputMessage")
SizeofRawInputDeviceList := 8
SizeofRidDeviceInfo := 32
RIM_TYPEMOUSE := 0
RIM_TYPEKEYBOARD := 1
RIM_TYPEHID := 2
RIDI_DEVICENAME := 0x20000007
RIDI_DEVICEINFO := 0x2000000b
RIDEV_INPUTSINK := 0x00000100
RID_INPUT := 0x10000003
Usage := 1
UsagePage := 12
; Use the script's main window rather than creating a GUI. DetectHiddenWindows must be ON.
HWND := WinExist("ahk_class AutoHotkey ahk_pid " DllCall("GetCurrentProcessId"))
; Keyboards are always Usage 6, Usage Page 1, Mice are Usage 2, Usage Page 1,
; HID devices specify their top level collection in the info block
VarSetCapacity(RawDevice, 12)
NumPut(RIDEV_INPUTSINK, RawDevice, 4)
NumPut(HWND, RawDevice, 8)
NumPut(UsagePage, RawDevice, 0, "UShort")
NumPut(Usage, RawDevice, 2, "UShort")
Res := DllCall("RegisterRawInputDevices", "UInt", &RawDevice, "UInt", 1, "UInt", 12)
if (Res = 0)
MsgBox, Failed to register for Natural Keyboard
InputMessage(wParam, lParam, msg, hwnd)
{
global DoCapture
global RIM_TYPEMOUSE, RIM_TYPEKEYBOARD, RIM_TYPEHID
global RID_INPUT
static LastKeyBits := 0
Critical ; May help responsiveness.
if (DoCapture = 0)
return
Res := DllCall("GetRawInputData", "UInt", lParam, "UInt", RID_INPUT, "UInt", 0, "UInt *", Size, "UInt", 16)
VarSetCapacity(Buffer, Size)
Res := DllCall("GetRawInputData", "UInt", lParam, "UInt", RID_INPUT, "UInt", &Buffer, "UInt *", Size, "UInt", 16)
Type := NumGet(Buffer, 0)
Size := NumGet(Buffer, 4)
Handle := NumGet(Buffer, 8)
if (Type = RIM_TYPEHID)
{
SizeHid := NumGet(Buffer, 16)
if SizeHid != 8 ; Only interested in inputs 8 bytes long.
return
InputCount := NumGet(Buffer, 20)
Loop %InputCount%
{
; NumGet is faster with (variable, offset) than (address).
Offset := 24 + ((A_Index - 1) * SizeHid)
; DECODING BASED ON MICROSOFT WIRELESS MEDIA DESKTOP 1000
; Events beginning with 04 or 05 seem to be meaningless spam.
; We are only interested in events beginning with 01.
if NumGet(Buffer, Offset, "Char") != 1
continue
; Some key-presses are identified by the second and third bytes.
Key := NumGet(Buffer, Offset + 1, "UShort")
; Some key states are stored in a bitfield.
KeyBits := NumGet(Buffer, Offset + 5, "UChar")
; Interpret 0000 as "some key released", but only if key bits haven't changed.
if (Key || KeyBits = LastKeyBits)
{
VarSetCapacity(KeyHex, 4)
DllCall("msvcrt\sprintf_s", "str", KeyHex, "uint", 5, "str", "%04X", "int", Key)
if IsLabel("HID" KeyHex)
;Gosub HID%KeyHex%
SetTimer, HID%KeyHex%, -1 ; Use a timer to avoid "locking" the message handler.
Debug("HID" KeyHex)
}
; Continue in case keys represented by "key bits" have also been pressed or released.
if (KeyBits != LastKeyBits)
{
; 1000000: F-lock ON/F-lock OFF.
; 0100000: F-lock pressed. Not updated immediately on release, therefore not useful.
; 0010000: [1]
; ...
; 0000010: [5]
; 0000001: Unused on this keyboard, but maybe used on others.
Loop 8
{
KeyBit := (1<<(A_Index-1))
if (KeyBits & KeyBit != LastKeyBits & KeyBit)
{
KeyBitLabel := "HID"
Loop % A_Index-1
KeyBitLabel .= "0"
KeyBitLabel .= "1"
Loop % 8-A_Index
KeyBitLabel .= "0"
if !(KeyBits & KeyBit)
KeyBitLabel .= "_UP"
if IsLabel(KeyBitLabel)
;Gosub %KeyBitLabel%
SEtTimer, %KeyBitLabel%, -1
Debug(KeyBitLabel " (" LastKeyBits " -> " KeyBits ")")
}
}
LastKeyBits := KeyBits
}
; The last byte appears to contain modifier key state (LCtrl, LShift, LAlt, etc.)
; but it is easier to handle modifier keys using standard AutoHotkey functions.
Debug("mod " NumGet(Buffer, Offset + 7, "Char"))
}
}
return
}
return
Debug(msg)
{
; OutputDebug, %msg%
; ToolTip % msg
return
}
HID10000000: ; F-lock ON
SoundPlay, F:\Downloads\Customization\Sounds\Wurt\user_free.wav
return
HID10000000_UP: ; F-lock OFF
SoundPlay, F:\Downloads\Customization\Sounds\Wurt\user_na.wav
return
HID00100000: ; [1]
HID00100000_UP:
HID00010000: ; [2]
HID00010000_UP:
HID00001000: ; [3]
HID00001000_UP:
HID00000100: ; [4]
HID00000100_UP:
HID00000010: ; [5]
HID00000010_UP:
MsgBox % A_ThisLabel
return
HID0199: ; Messenger
FKey("")
Send #e
return
HID0182: ; Favourites
FKey("")
Send #q
return
HID01A2: ; Flip-3D
FKey("HID01A2_UP:") ; Run HID01A2_UP when FKey() is called with a different value.
Send {LWin Down}{Tab}
return
HID01A2_UP: ; The next HIDxxxx where xxxx is not 01A2.
Send {LWin Up}
return
HID0095:
FKey("F1")
return
HID021A:
FKey("F2")
return
HID0279:
FKey("F3")
return
HID0201:
FKey("F4")
return
HID0202:
FKey("F5")
return
HID0203:
FKey("F6")
return
HID0289:
FKey("F7")
return
HID028B:
FKey("F8")
return
HID028C:
FKey("F9")
return
HID01AB:
FKey("F10")
return
HID0207:
FKey("F11")
return
HID0208:
FKey("F12")
return
HID0000:
FKey("")
return
FKey(k)
{
static last_k := ""
if last_k && last_k != k
{
if SubStr(last_k,0) = ":" && IsLabel(SubStr(last_k,1,-1))
Gosub % SubStr(last_k,1,-1)
else
Send {Blind}{%last_k% Up}
last_k := ""
}
if k && (SubStr(last_k,0) != ":" || !IsLabel(SubStr(last_k,1,-1)))
Send {Blind}{%k% Down}
last_k := k
} | It isn't perfect, but seems to work well for my purposes. |
|
| Back to top |
|
 |
ddh819
Joined: 27 Dec 2006 Posts: 22
|
Posted: Fri Feb 20, 2009 3:51 pm Post subject: |
|
|
I'd like to use this to remap the buttons on a Kensington presentation remote (which simulate PgUp, PgDn, F5 and "b") since Micha's DLL can't tell the difference between it and the regular keyboard keys. But I don't understand how it works.
This is what I get when I press all the keys using Shaun's test script:
HND 1508478 KBD ScanCode 73 VKey 33 Msg 256
HND 1508478 KBD ScanCode 73 VKey 33 Msg 257
HND 1508478 KBD ScanCode 81 VKey 34 Msg 256
HND 1508478 KBD ScanCode 81 VKey 34 Msg 257
HND 1508478 KBD ScanCode 63 VKey 116 Msg 256
HND 1508478 KBD ScanCode 63 VKey 116 Msg 257
HND 1508478 KBD ScanCode 48 VKey 66 Msg 256
HND 1508478 KBD ScanCode 48 VKey 66 Msg 257
How do i translate these into hotkeys? |
|
| Back to top |
|
 |
mai9
Joined: 17 Mar 2008 Posts: 62 Location: Barcelona, Catalonia
|
Posted: Wed Mar 11, 2009 7:41 pm Post subject: |
|
|
I can't help you much because I don't know a lot, but I have the same keyboard as Shaun and the string number that will be used to call the key is not present in what you posted.
If I use the HIDList and press the "My Favorites" key, it captures:
| Code: | HND 65637 HID Size 8 Count 1 Ptr 43656788
Input 0182010000010000
HND 65637 HID Size 8 Count 1 Ptr 43656788
Input 0100000000010000 |
as you can see what you posted lacks the "input" string, maybe your kensington is not a HID device. In my keyboard when I press space, HIDList it doesn't list an "input" neither. Seems that it's only for those special keys. |
|
| Back to top |
|
 |
TheGood
Joined: 30 Jul 2007 Posts: 580
|
Posted: Thu Mar 12, 2009 7:00 pm Post subject: |
|
|
| ddh819 wrote: | I'd like to use this to remap the buttons on a Kensington presentation remote (which simulate PgUp, PgDn, F5 and "b") since Micha's DLL can't tell the difference between it and the regular keyboard keys. But I don't understand how it works.
This is what I get when I press all the keys using Shaun's test script:
HND 1508478 KBD ScanCode 73 VKey 33 Msg 256
HND 1508478 KBD ScanCode 73 VKey 33 Msg 257
HND 1508478 KBD ScanCode 81 VKey 34 Msg 256
HND 1508478 KBD ScanCode 81 VKey 34 Msg 257
HND 1508478 KBD ScanCode 63 VKey 116 Msg 256
HND 1508478 KBD ScanCode 63 VKey 116 Msg 257
HND 1508478 KBD ScanCode 48 VKey 66 Msg 256
HND 1508478 KBD ScanCode 48 VKey 66 Msg 257
How do i translate these into hotkeys? |
You should look into AHKHID, an HID wrapper I made.
With the examples included (especially Example 2) you can find out exactly what each key on your remote sends and then you can make your own script with an OnMessage function that relays the event to a sub. Try it out and if you have problems, post in the other thread and I'll help you  |
|
| Back to top |
|
 |
j0dan
Joined: 02 Feb 2009 Posts: 11 Location: Abbotsford, BC, Canada
|
Posted: Tue Mar 24, 2009 5:27 pm Post subject: |
|
|
It looks like modifiers like the windows key can be applied to the favorite buttons on the natural keyboard. The codes are the same except the last digit is an 8 instead of 0 for Windows.
But I'm not sure how to stop the start menu from coming up every time I press it. Ideas?
| Code: | 0100000000050008:
MsgBox Windows Favorites 1
; The Windows button press still goes to the OS
return
|
|
|
| Back to top |
|
 |
popoycanton
Joined: 12 Sep 2009 Posts: 2
|
Posted: Sat Sep 12, 2009 3:23 pm Post subject: |
|
|
| lilalurl.T32 wrote: | Fantastic job Shaun.
Edit: Just thought of another application for your script, remapping the numpad additional keys (= ( ) and <-). Here are the results of my test for people interested.
The backspace key behaves as a normal backspace key, so I guess it can't be remapped to something else.
However the three others register as speficic HID keys. Here are the values:
| Code: | ;numpad=
0100006700010000:
msgbox equal
return
;numpad(
010000B600010000:
msgbox (
return
;numpad)
010000B700010000:
msgbox )
return |
|
So, how do you actually use this in a script? Sorry I'm new to autohotkeys & learning as i go. I've learned remaping with with send, but that's as far as I've gotten.  |
|
| Back to top |
|
 |
lilalurl.T32
Joined: 17 May 2007 Posts: 391 Location: Titan
|
Posted: Sat Sep 12, 2009 9:42 pm Post subject: |
|
|
| popoycanton wrote: | | So, how do you actually use this in a script? |
Take the second script posted by Shaun (the one that begins with ; Capture input from the "Zoom" slider on the Natural Keyboard 4000
; and use it to scroll up and scroll down ).
Then, you need to modify the part that is between line 147 and line 166 (i.e. just after ";Debug("Done") Return " and until "Debug(msg)".
There you will put the code for the keys you want to remap (you can find the code using Shaun's first script) and what you want the key to do.
So for instance, 0100006700010000 is what I found using the first script for the numpad equal key. What you have quoted is just the code and a msgbox that will be triggered when you press the correct key (to verify if the code is correct).
Hence, you just add this in the part I mentioned (or replace the zoom part if you don't want it) and put whatever you want the key to do instead of msgbox whatever.[/quote]
Then you run the script and as long as it is active, the key will be remapped.
________
VAPORIZER REVIEW
Last edited by lilalurl.T32 on Sun Mar 13, 2011 6:44 am; edited 2 times in total |
|
| Back to top |
|
 |
popoycanton
Joined: 12 Sep 2009 Posts: 2
|
Posted: Sun Sep 13, 2009 12:22 am Post subject: |
|
|
@lilalurl.T32
thanks chief.
That much I understand, tried it out & was a success  |
|
| 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
|