Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

AHKHID - An AHK implementation of the HID functions


  • Please log in to reply
456 replies to this topic
specter333
  • Members
  • 627 posts
  • Last active: Oct 07 2016 07:43 AM
  • Joined: 15 Jan 2007
I have read that you can distinguish between two keyboards but I don't know how it's done. I believe it is somewhere in this topic, it's a lot of post to read through but it's here somewhere.

AmourSpirit
  • Members
  • 93 posts
  • Last active: Mar 01 2016 04:28 PM
  • Joined: 01 Dec 2010

seems that this HID-related scripting might be able to do what I need.
Could you please support with this a bit?

Can you distinguish if a keypress came from a netbook's/UMPC's internal keyboard or a keyboard attached to the USB port?
I'd like to implment some hotkeys and hotstrings only for the built-in keyboard, but not for an external one...

Thanks!
Daniel


You could start by isolating something different about the keyboards if possible.
Once you distinguish which input it coming form which keyboard you can see if you can handle them differently somehow.
My Firefly mini remote reports a keyboard and I wanted to use the input differently.
The Remote control has both a keyboard and other control input
so I registered them both
;Register Remote Control with RIDEV_INPUTSINK (so that data is received even in the background)
r := AHKHID_Register(12, 1, hGui, RIDEV_INPUTSINK )

; Register Keyboard input and pass through keys from keyboard input
k := AHKHID_Register(1, 6, hGui, RIDEV_INPUTSINK )
Here is a code snippit
InputMsg(wParam, lParam) {
    Local devh, iKey, sLabel, r ,vKey
   
      
    Critical
   ;Get device type
    r := AHKHID_GetInputInfo(lParam, II_DEVTYPE) 
        
    If (r = RIM_TYPEKEYBOARD) {
        ;Get handle of device
        devh := AHKHID_GetInputInfo(lParam, II_DEVHANDLE)
        iKeyCount := AHKHID_GetDevInfo(devh, DI_KBD_NUMBEROFKEYSTOTAL, True)
        ; Firefly remote shows as 264 keys so we will take advantage of that to isolate
        ; the remote only keyboard input
        if (iKeycount > 0 && iKeyCount = 264) {
           ; This is input from the Firefly Mini keyboard buttons 0-9, Arrow keys, enter key, etc
            vKey := AHKHID_GetInputInfo(lParam, II_KBD_VKEY)
            ;Call the appropriate sub if it exists
                sLabel := sPrefix "__" vKey 
                If IsLabel(sLabel)
                    Gosub, %sLabel%
                
            return
        }
    } Else If (r = RIM_TYPEHID) {
        ;Get handle of device
        devh := AHKHID_GetInputInfo(lParam, II_DEVHANDLE)
        If (devh <> -1) ;Check that it is my Firefly Mini
        And (AHKHID_GetDevInfo(devh, DI_DEVTYPE, True) = RIM_TYPEHID)
        And (AHKHID_GetDevInfo(devh, DI_HID_VENDORID, True) = 4659)
        And (AHKHID_GetDevInfo(devh, DI_HID_PRODUCTID, True) = 57351)
        And (AHKHID_GetDevInfo(devh, DI_HID_VERSIONNUMBER, True) = 256) {
           ; This is the input from the firefly mini remote that is not part of the keyboard.
            ;Get data
            iKey := AHKHID_GetInputData(lParam, uData)

            ;Check for error
            If (iKey <> -1) {
               
                ;Get keycode (located at the 2nd byte)
                iKey := NumGet(uData, 1, "UChar")

                ;Call the appropriate sub if it exists
                sLabel := sPrefix "_" iKey
                If IsLabel(sLabel)
                    Gosub, %sLabel% 
            }
        }
    }
   
}
The remote reports 264 keys for some reason so that is what I used note the line "if (iKeycount > 0 && iKeyCount = 264)"

Hope that helps

bidomo
  • Members
  • 62 posts
  • Last active: Feb 04 2019 06:30 AM
  • Joined: 05 Feb 2009
Integrated Keyboards used to be PS/2, don't know if still the same for most model.

AmourSpirit
  • Members
  • 93 posts
  • Last active: Mar 01 2016 04:28 PM
  • Joined: 01 Dec 2010
Is there a way to to capture information about the input device outside of IntputMsg

This line in inside the InputMsg(wParam, lParam) Sub

;Get handle of device
devh := AHKHID_GetInputInfo(lParam, II_DEVHANDLE)

It uses lParam to get the Device Handle. I want to do this outside of the InputMsg sub

What I am tring to accomplish is to use a HotKey with a label
For example
Hotkey, 4,Default52 ; send number 4 and conditionally remap

I want to be able to process in the label what keyboard or remote the input came from inside the label.
The issue is right now I don't seem to have access to a lParam to use AHKHID_GetInputInfo from a Hotkey Label

Unfortunately the Keypress fires before the inputMsg so by the time InputMsg gets the input message it is already too late.

I think it could solve a lot of issues with remote controls that have both remote control input keys and Normal Keyboard input keys on them.

Bruno C
  • Guests
  • Last active:
  • Joined: --
Hi
Did anybody manage to implement output communication using AHK?

AHKHID(great work) manages peripheral input "only".
I need to write to my HID usb peripheral... I bet i am not the first one.
:roll:

specter333
  • Members
  • 627 posts
  • Last active: Oct 07 2016 07:43 AM
  • Joined: 15 Jan 2007
You should read through the HID functions and see if any are output features. Can you describe what you are wanting to do specifically?

The only HID output I can think of off the top of my head is monitor settings and AHKHID can not control that.

I had a similar question TheGood was able to answer for me. There are two HID DLLs that can be used, a standard and an advanced. AHKHID uses the standard dll so some HID functions are not possible, monitors being one of them and in my time using it I haven't noticed any output features, but that doesn't mean there aren't any.

I have gotten someone to help me start writing a library for the advanced dll but so far we have done very little, we sorta lost interest in the project. But I'm sure if the functions aren't available now they would be in the advanced dll.

BrunoC
  • Members
  • 24 posts
  • Last active: Mar 16 2011 08:20 PM
  • Joined: 09 Mar 2011
Hi need to send many packets () not just bytes (so NumPut is no good) to my USB device.

My peripheral is the Hercules tunes remote (RF remote).

It's a standard 9 buttons peripheral (up/down/left/right/ok/ Vol Up/Vol Dwn /scroll up/scroll dwn). The buttons are easily intercepted with AHKHID.

The intersting point of this peripheral is that it has an LCD screen and an internal memory: in the standard use, it gets from the PC all the iTune library, the user can use the LCD to scroll across the songs (songs list received by te pc) ...

So I wish to send my own lists to the peripheral ( and to control my MediaCenter XBMC).

specter333
  • Members
  • 627 posts
  • Last active: Oct 07 2016 07:43 AM
  • Joined: 15 Jan 2007
That is a very interesting project but I don't think the returning the info to the device would fall under the HID category. I use other outputs though usb that use there own dll or one is called an sdk, I don't have any actual training in these things so I may not be referring to these correctly.

Point is everything I've seen that receives info from AHK has it's own specific method that AHK accesses.

BrunoC
  • Members
  • 24 posts
  • Last active: Mar 16 2011 08:20 PM
  • Joined: 09 Mar 2011
Once I'll found the way to use to send any byte to the peripheral I'll be able then to write an AHK high level library

specter333
  • Members
  • 627 posts
  • Last active: Oct 07 2016 07:43 AM
  • Joined: 15 Jan 2007
I did a little reading on the Tunes Remote. It looks like it gets a playlist from the PC and it is dependent on Quicktime for communication, is this correct? If so you should look into how Quicktime communicates with it and controlling Quicktime with AHK.

BrunoC
  • Members
  • 24 posts
  • Last active: Mar 16 2011 08:20 PM
  • Joined: 09 Mar 2011
I've sniffed the USB/PC exchanges.

I am able to decode the protocoll, the missing point is sending the bytes to the USB peripheral ... and this should be done by AHK ...

The other solution is to write down a prog from zero but don't wanna pixx me off with install of the Microsoft VisualC, AHK should do the trick with few lines of code

ranamen
  • Members
  • 1 posts
  • Last active: May 07 2011 02:34 AM
  • Joined: 07 May 2011
hello guys!
i just got a new keyboard+mouse wireless combo. this mouse has forward/backward buttons with work fine with ahk (xmousebutton1&2), but it has 2 currently useless zoom buttons. since theyre not directly detected, i tried HID input. after some search i found this:
http://technomaniac.comze.com/?p=316
this script uses ahkhid for HID input and its exactly the same mouse im using, but when i try running it i get this error:

"Error: Call to nonexistent function.
Specifically: AHKHID_UseConstants()"

i tried using the ahkhid example scripts but got the same error. i already placed ahkhid.ahk on the same folder of the scripts but still get this error.
can somebody please give me a little help with this?

specter333
  • Members
  • 627 posts
  • Last active: Oct 07 2016 07:43 AM
  • Joined: 15 Jan 2007

i already placed ahkhid.ahk on the same folder of the scripts but still get this error.

Read this on #include and Library functions to help explain how to use AHKHID.ahk.
http://www.autohotke...ons.htm#include

I your going to keep AHKHID in the folder with your script you need to use #Include. It's easier to place it in the lib folder in c:program files\AutoHotkey\lib then the script will find it on it's own.

A couple of topics that may make things a little easier for you.

This is the examples from the first post of this topic rolled into one easier to use giu.
http://www.autohotke...pic.php?t=67522
At the bottom of the help file is a script with the section marked where you should insert the info from your device.

The other is an automation script that can take input from HID devices, keyboard input, mouse input or many other input sources and adds them to subroutines for you.
http://www.autohotke...pic.php?t=71046

Chances are your extra mouse buttons will be seen as "HID" devices so any of these should work for you.

Emisand
  • Members
  • 1 posts
  • Last active: Jun 21 2011 01:19 AM
  • Joined: 19 Jun 2011
Hello Guys

I am new at AHK, but I learned it quickly.

I have a Logitech Keyboard Controller
<!-- m -->http://www.logitech.... ... controller<!-- m -->

It's a Logitech Keyboard with Touchpad specially designed for Google TV, but it also works on PC using the Logitech Unifying receiver provided with it.

So when I use it with my PC, some special keys don't work.
I investigated it deeply and found Raw Input.

Using AHKHID (That is implemented with Raw Input) I could capture this special keys, then I have made a script for managing those keys using AHK and AHKHID.

Here it is:

/*!

Script Developed by Emisand

Logitech Keyboard Controller (LKC)
Model: K700

Vendor ID: 	1133
Product ID: 	50475
Version Number: 4610
Usage Page: 	12
Usage: 		1

Key Name		Raw Data	Description
--------------		----------	-------------------------
LKC_RELEASE		0300000000	Key released event
LKC_FN			03F0010000	FN Key
LKC_TV_LEFT		0389000000	Left TV Key
LKC_GUIDE		038D000000	Guide Key
LKC_DVR			039A000000	DVR Key
LKC_AVR			03F3010000	AVR Key
LKC_STB			03FC010000	STB Key
LKC_TV_RIGHT		03FE010000	Right TV Key
LKC_FN_AVR		03F001F201	FN + AVR
LKC_FN_STB		03F001FB01	FN + STB
LKC_FN_TV		03F001FD01	FN + Right TV
LKC_CH_UP		039C000000	Channel Up Key
LKC_CH_DN		039D000000	Channel Down Key
LKC_FAV			032A020000	Favorites Key (Star)
LKC_SCREEN		03F1010000	Screen Key (Squares)
LKC_SK_A		03F001F501	Special Key A (FN+5)
LKC_SK_B		03F001F401	Special Key B (FN+6)
LKC_SK_C		03F001F701	Special Key C (FN+7)
LKC_SK_D		03F001F601	Special Key D (FN+8)
LKC_MENU		03F001EF01	Menu Key (FN+9)
LKC_INFO		03F001FF01	Info Key (FN+0)
LKC_ZOOM_OUT		03F0012E02	Zoom Out Key (FN+-)
LKC_ZOOM_IN		03F0012D02	Zoom In Key (FM+=)
LKC_REW			03B4000000	Rewind Key
LKC_PLAY		03B0000000	Play Key
LKC_PAUSE		03B1000000	Pause Key
LKC_FF			03B3000000	Fast Forward Key
LKC_PREV		03F001B600	Previous Track (FN+REW)
LKC_STOP		03F001B700	Stop Key (FN+Pause)
LKC_NEXT		03F001B500	Next Track (FN+FF)
LKC_REC			03F001B200	Rec Key (FN+Fav)
LKC_HOME		0323020000	Home Key
LKC_BACK		0324020000	Back key (Arrow)

*/

;Loads the required AHKHID Script
#Include AHKHID.ahk

;Create GUI to receive messages
Gui, +LastFound
hGui := WinExist()

;Intercept WM_INPUT messages
WM_INPUT := 0xFF
OnMessage(WM_INPUT, "InputMsg")

;Register Remote Control with RIDEV_INPUTSINK (so that data is received even in the background)
r := AHKHID_Register(12, 1, hGui, RIDEV_INPUTSINK)

InputMsg(wParam, lParam) 
{
    Local devh, iKey, sLabel
   
    Critical
   
    ;Get handle of device
    devh := AHKHID_GetInputInfo(lParam, II_DEVHANDLE)
   
    ;Check for error
    If (devh <> -1) ;Check that it is  Logitech Keyboard Controller
        And (AHKHID_GetDevInfo(devh, DI_DEVTYPE, True) = RIM_TYPEHID)
        And (AHKHID_GetDevInfo(devh, DI_HID_VENDORID, True) = 1133)
        And (AHKHID_GetDevInfo(devh, DI_HID_PRODUCTID, True) = 50475)
        And (AHKHID_GetDevInfo(devh, DI_HID_VERSIONNUMBER, True) = 4610) 
    {
       
        ;Get data
        iKey := AHKHID_GetInputData(lParam, uData)
       
        ;Check for error
        If (iKey <> -1) 
	{
		byte1 := NumGet(uData, 1, "UChar")
		byte2 := NumGet(uData, 2, "UChar")
		byte3 := NumGet(uData, 3, "UChar")
		byte4 := NumGet(uData, 4, "UChar")

		sLabel := "UNDEFINED"

		If(byte1 = 0x0 And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_RELEASE"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_FN"

		If(byte1 = 0x89 And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_TV_LEFT"

		If(byte1 = 0x8D And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_GUIDE"

		If(byte1 = 0x9A And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_DVR"

		If(byte1 = 0xF3 And byte2 = 0x1 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_AVR"

		If(byte1 = 0xFC And byte2 = 0x1 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_STB"

		If(byte1 = 0xFE And byte2 = 0x1 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_TV_RIGHT"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xF2 And byte4 = 0x1)
			sLabel := "LKC_FN_AVR"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xFB And byte4 = 0x1)
			sLabel := "LKC_FN_STB"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xFD And byte4 = 0x1)
			sLabel := "LKC_FN_TV"

		If(byte1 = 0x9C And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_CH_UP"

		If(byte1 = 0x9D And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_CH_DN"

		If(byte1 = 0x2A And byte2 = 0x2 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_FAV"

		If(byte1 = 0xF1 And byte2 = 0x1 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_SCREEN"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xF5 And byte4 = 0x1)
			sLabel := "LKC_SK_A"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xF4 And byte4 = 0x1)
			sLabel := "LKC_SK_B"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xF7 And byte4 = 0x1)
			sLabel := "LKC_SK_C"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xF6 And byte4 = 0x1)
			sLabel := "LKC_SK_D"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xEF And byte4 = 0x1)
			sLabel := "LKC_MENU"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xFF And byte4 = 0x1)
			sLabel := "LKC_INFO"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0x2E And byte4 = 0x2)
			sLabel := "LKC_ZOOM_OUT"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0x2D And byte4 = 0x2)
			sLabel := "LKC_ZOOM_IN"

		If(byte1 = 0xB4 And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_REW"

		If(byte1 = 0xB0 And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_PLAY"

		If(byte1 = 0xB1 And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_PAUSE"

		If(byte1 = 0xB3 And byte2 = 0x0 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_FF"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xB6 And byte4 = 0x0)
			sLabel := "LKC_PREV"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xB7 And byte4 = 0x0)
			sLabel := "LKC_STOP"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xB5 And byte4 = 0x0)
			sLabel := "LKC_NEXT"

		If(byte1 = 0xF0 And byte2 = 0x1 And byte3 = 0xB2 And byte4 = 0x0)
			sLabel := "LKC_REC"

		If(byte1 = 0x23 And byte2 = 0x2 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_HOME"

		If(byte1 = 0x24 And byte2 = 0x2 And byte3 = 0x0 And byte4 = 0x0)
			sLabel := "LKC_BACK"

		If IsLabel(sLabel)
			Gosub, %sLabel%
		
        }
    }
}

LKC_RELEASE: 	; Key released event
Return


LKC_FN: 	; FN Key
Return


LKC_TV_LEFT: 	; Left TV Key
	SendInput LKC_TV_LEFT {Enter}
Return


LKC_GUIDE: 	; Guide Key
	SendInput LKC_GUIDE {Enter}
Return


LKC_DVR: 	; DVR Key
	SendInput LKC_DVR {Enter}
Return


LKC_AVR: 	; AVR Key
	SendInput LKC_AVR {Enter}
Return


LKC_STB: 	; STB Key
	SendInput LKC_STB {Enter}
Return


LKC_TV_RIGHT: 	; Right TV Key
	SendInput LKC_TV_RIGHT {Enter}
Return


LKC_FN_AVR: 	; FN + AVR
	SendInput LKC_FN_AVR {Enter}
Return


LKC_FN_STB: 	; FN + STB
	SendInput LKC_FN_STB {Enter}
Return


LKC_FN_TV: 	; FN + Right TV
	SendInput LKC_FN_TV {Enter}
Return


LKC_CH_UP: 	; Channel Up Key
	SendInput LKC_CH_UP {Enter}
Return


LKC_CH_DN: 	; Channel Down Key
	SendInput LKC_CH_DN {Enter}
Return


LKC_FAV: 	; Favorites Key (Star)
	SendInput LKC_FAV {Enter}
Return


LKC_SCREEN: 	; Screen Key (Squares)
	SendInput LKC_SCREEN {Enter}
Return


LKC_SK_A: 	; Special Key A (FN+5)
	SendInput LKC_SK_A {Enter}
Return


LKC_SK_B: 	; Special Key B (FN+6)
	SendInput LKC_SK_B {Enter}
Return


LKC_SK_C: 	; Special Key C (FN+7)
	SendInput LKC_SK_C {Enter}
Return


LKC_SK_D: 	; Special Key D (FN+8)
	SendInput LKC_SK_D {Enter}
Return


LKC_MENU: 	; Menu Key (FN+9)
	SendInput LKC_MENU {Enter}
Return


LKC_INFO: 	; Info Key (FN+0)
	SendInput LKC_INFO {Enter}
Return


LKC_ZOOM_OUT: 	; Zoom Out Key (FN+-)
	SendInput LKC_ZOOM_OUT {Enter}
Return


LKC_ZOOM_IN: 	; Zoom In Key (FM+=)
	SendInput LKC_ZOOM_IN {Enter}
Return


LKC_REW: 	; Rewind Key
	SendInput LKC_REW {Enter}
Return


LKC_PLAY: 	; Play Key
	SendInput LKC_PLAY {Enter}
Return


LKC_PAUSE: 	; Pause Key
	SendInput LKC_PAUSE {Enter}
Return


LKC_FF: 	; Fast Forward Key
	SendInput LKC_FF {Enter}
Return


LKC_PREV: 	; Previous Track (FN+REW)
	SendInput LKC_PREV {Enter}
Return


LKC_STOP: 	; Stop Key (FN+Pause)
	SendInput LKC_STOP {Enter}
Return


LKC_NEXT: 	; Next Track (FN+FF)
	SendInput LKC_NEXT {Enter}
Return


LKC_REC: 	; Rec Key (FN+Fav)
	SendInput LKC_REC {Enter}
Return


LKC_HOME: 	; Home Key
	SendInput LKC_HOME {Enter}
Return


LKC_BACK: 	; Back key (Arrow)
	SendInput LKC_BACK {Enter}
Return

I have properly commented every key, showing a name I picked for them, the raw data sent by the keyboard and a description of the key.

Then I have managed the WM_INPUT Message so for each recognized raw input data I let the script go to a tag and do any specific operation with that key.

For now, it just sends an input with the key name, so it's open to customize.

You can recognize some more keys of this keybord that I have not listed, for example FN+1, FN+2, FN+3, FN+4, you can get the raw data of those keystrokes using AHKHID.

I hope this can help someone.

blake@assuremo.com
  • Guests
  • Last active:
  • Joined: --
Thanks for such a great addition to the AHK toolset.
When I open "example 1" I don't have any HID devices listed in any folder, though I know I have many installed. When I use autohotkeyRemoteControl, it detects about 23 devices. What am I doing incorrectly?