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
TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007

It looks like windows is returning the keyboard output first when you register 1/6

When you plug in the receiver, the plug-and-play driver creates a keyboard device which is used to send keyboard keys for certain remote keys. In the eyes of the computer, there is no difference between the keyboard event coming from the keyboard and the keyboard event coming from the remote.

If you want to differentiate between the two, then you need to uninstall the keyboard device associated to the remote (so that no more keyboard events are created) and you can then concentrate on the other TLCs the remote operates on (which you can find through the "Other" tab of Example 1). This means you'll still be able to tell when the Up key is pressed on the remote, but it won't be broadcasted as a keyboard event (after you uninstall the keyboard device).

Hope this helps.

kenny782
  • Members
  • 11 posts
  • Last active: Sep 01 2010 12:43 AM
  • Joined: 18 May 2009
ahh I got it.

I'm writing this for my desktop, but my laptop has a remote receiver too.
It's designed to be used as media center.

So I've been testing using the same remote and my laptop.

I just discovered if I use my desktop the remote always returns vendor ID 81
And my keyboard returns 4.

So I'll just use If VENDOR_ID <> 81


Damn HP can't just use standard codes lol
Sorry for all the questions.
But thanks for the help this is great :)

Kenny

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
No problem! :D
Do you have the exact same remote as me? If so, you can probably use the same script I posted.
Also, HID devices of type RIM_TYPEKEYBOARD do not have attributes such as VendorID, ProductID, etc... These are for HID devices of type RIM_TYPEHID. So, it's not safe to discriminate on those.
Can I see the code you're using? I can help you setting it up. :wink:

kenny782
  • Members
  • 11 posts
  • Last active: Sep 01 2010 12:43 AM
  • Joined: 18 May 2009
Here's what I've got so far :-)

My If/Else statements seem needlessly long to me. I think I did something wrong lol

I looked at the help file but I couldn't get them to work any other way


;Must be in auto-execute section if I want to use the constants
#Include %A_ScriptDir%\AHKHID.ahk

AppActive = 1

;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 := HID_Register(1, 6, hGui, RIDEV_INPUTSINK)

;Prefix loop
Loop {
    Sleep 1000
}

Return

InputMsg(wParam, lParam) {
    Local devh, iKey, sLabel
   
    Critical
   
    ;Get handle of device
    devh := HID_GetInputInfo(lParam, II_DEVHANDLE)
    ;Check for error
    If (devh <> -1) ;Check that it is NOT my remote.
        And (HID_GetDevInfo(devh, DI_HID_VENDORID, True) <> 81)
        {
       
        ;Get data
        iKey := HID_GetInputInfo(lParam, II_KBD_VKEY) ;Get Vkey code

       MsgBox %iKey%
       
        If iKey = 114
        {
        Gosub, ToggleApp ;F3 = 114
        MsgBox "F3 Hit"
        }
        Else
        {
        Gosub, LockPC
        }
    }
}


ToggleApp: ;More
    If AppActive = 1
    {
    AppActive = 0
    }
    Else
    {
    AppActive = 1   
    }   
    
Return

LockPC: ;Channel Up
    If AppActive = 1
    {
    Run rundll32.exe user32.dll`,LockWorkStation`
    }
Return


Faolin
  • Members
  • 8 posts
  • Last active: Apr 25 2011 11:01 PM
  • Joined: 14 May 2009

Also, HID devices of type RIM_TYPEKEYBOARD do not have attributes such as VendorID, ProductID, etc... These are for HID devices of type RIM_TYPEHID. So, it's not safe to discriminate on those.


huh... just when I thought I was learning something ;) This is some complicated business =P

Let me know if it works out!


Indeed it did! It was that hGui parameter, after all. Not only did it solve the flag problem, but it also made the registration instantaneous. I tested some simple (and complex) keystrokes in-game and it all works wonderfully.

All that's left to do is polish the script. There are a couple quirks with a device like this. Notice I have to hard-code the initial rValue of the device for all switches in the off position. I'm not sure if there's any way to poll the device for its current (or last?) output value. That might help in fixing the situation where I flip a switch while the script is not active and it desyncronizes the script's rValue from the device's actual last output value. It doesn't create a permanent error for the script, but it causes only the next switch flip (after the desync) not to trigger any keypresses since the iDiff then becomes some unforeseen value. Subsequent flips are registered properly since the rValue contains the accurate value after that first flip. If there was a way to auto-poll the device, that would solve this problem entirely.

Also, is it realistic (i.e. fast enough) to hope to assign keystrokes on-the-fly in a GUI? I'm thinking of populating a listbox with keystrokes/sleeps for each switch on the panel. Then the script would read the contents of the box each time and execute its contents.

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007

Here's what I've got so far

Instead of using DI_HID_VENDORID, you should use DI_KBD_TYPE, since you're manipulating keyboards. Don't worry, it'll return the same values (since those two flags have the same constant value). It would look like this:
If (devh <> -1) ;Check that it is NOT my remote.
        And (HID_GetDevInfo(devh, DI_KBD_TYPE, True) <> 81)

Also, a few AHK tricks ;):

- Since AppActive is just a boolean variable, you can use AppActive := True and AppActive := False instead of = 0 and = 1. It's the same thing, but cleaner (and easier to read IMO).
- You can replace
If AppActive = 1
    {
    AppActive = 0
    }
    Else
    {
    AppActive = 1   
    }
by
AppActive := Not AppActive
- You can replace
If AppActive = 1
    {
    Run rundll32.exe user32.dll`,LockWorkStation`
    }
by
If AppActive
    Run rundll32.exe user32.dll`,LockWorkStation`
- If you don't need the prefix loop, you can remove it. Since you're using an OnMessage sub, your script is persistent, which means that it won't exit when it gets to Return.

Let me know if you have any other questions!

huh... just when I thought I was learning something ;) This is some complicated business =P

It's simple! :)
Look at the flags you can use with HID_GetDevInfo(), all the ones starting by DI_MSE are for mice, DI_KBD are for keyboards, and DI_HID are for HID devices (the ones in the "Other" section of Example 1).

There are a couple quirks with a device like this.

I'm glad to hear it works! As for your problem, I'm sorry to tell you there's no way to "ask" the device what its status is. At least not with AHKHID. It really sucks that you have to rely on differentials to trigger the events. But I don't see a way around it. Sorry. :(

Also, is it realistic (i.e. fast enough) to hope to assign keystrokes on-the-fly in a GUI?

Sure! I don't see why not. There are different ways of implementing it, but it's totally doable. Personally, I don't mind quickly editing the script file so that I can change what each event does (and have a hotkey to reload the script).

If your goal is to be able to have multiple (different) actions for the same trigger, you might find modifier keys useful. For example, for one HID device I have (a USB volume knob), I use modifier keys to assign multiple actions for the same movement. For example, Ctrl+Turn controls the Master volume, while Shift+Turn controls the Wave volume.

There are other things you can do. For example, you can set the actions to execute to depend on the active window. Then, if you're in a game, it'll do something, but if you're not, it can do another thing.

mmkisser
  • Guests
  • Last active:
  • Joined: --
Dear TheGood:

Can you give a sample with your script?

Thank you a lot.

tyxiang
  • Members
  • 12 posts
  • Last active: Sep 12 2009 07:53 AM
  • Joined: 26 Nov 2008
I main:
can you give a sample with your script for wiimote.

Thank you a lot

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
Unfortunately, I can't help you because I don't have the material necessary to test it. But the first step would be to hook up the Wiimote to the computer so that it shows up as a HID device (and you can see it in Example 1). I know this can be done, but I can't help you because I have no experience at all.

If you figure it out, I can try to help you making sense of it.

callummcl
  • Guests
  • Last active:
  • Joined: --
Hi, I recently purchased a Leadtek DVB dongle for my notebook. I wanted to customize the buttons on the remote and decided to use AHK to implement this. I used example 2 to find the device and similarly to ddh819 my remote is classified as a keyboard. I tried using the sample codes provided but they didn't work. After reading though AHKHID i finally figured out how to distinguish between the remote and keyboard.

Although, I cant stop the remote from sending keystrokes, the sample code provided used $b::Return before the function, this catches all key inputs ("b" in this example) but does not execute the Inputmsg function. Even if the function is called on a hotkey how is "lparam" found?

Any help would be much appreciated I am quite new to AHK but can manage my way around the code.

cheers

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
OK, are you sure the device only appears in the keyboard section? Nothing new comes up in the other section?

The $b::Return is only used to completely cancel all b presses (both from the keyboard and your remote). What you need to do then is to send the b key when your actual keyboard sends it. If you've been able to tell apart the keyboard and the remote by now, it shouldn't be too difficult.

Can you post your script? It'll help me help you. :D

Thracx
  • Members
  • 14 posts
  • Last active: Jul 08 2011 10:29 PM
  • Joined: 12 Mar 2007
TheGood - thank you! You did some excellent work - not only in getting those scripts together, but in documenting how you used them yourself as a case study. Bravo!


I was mostly successful using TheGood's scripts to debug the issues I've been having trying to get my new PC IR Receiver to work the way I want it too. If you don't have a 'PiPi' remote or use XBMC, feel free to ignore the rest of my post - I'm just posting an overview of my experience here in case someone else has a similar problem and will be able to find this post.

I have a rather generic IR receiver & remote that I got off Ebay, the only labeling being a "PiPi Media Center Remote". It only cost <$9 so I didn't expect much - works much better than I thought it would!

I've been trying to get my Logitech Harmony 550 remote to work with XBMC for Windows using this receiver. The new remote wasn't in Logitech's database, although I was able to 'learn' all the commands to the remote. This isn't that great, as I was hoping to be able to have a lot more button options to use with this IR receiver, but for some reason nearly every other IR signal I can send causes the receiver to 'blink', but nothing seems to be visible to AHK or Girder.

In short, most of the keys from the remote itself are sent via a HID Keyboard (stuff like Ctrl+p for 'Play'), but the Vol+/- are also sent via an 'Other' HID device
(they also get sent separately from the 'keyboard' source, but NOT repeating so I do hope to get AHK working using TheGood's AHK method). The 'Media Center' button is sent by the second 'Other' HID device and nothing else - so to get this button I'll also need AHK to register a message handler for me.

Since there are a limited number of keys on the provided remote, I'll be wanting to get every last key working. I've tried throwing other IR signals at the receiver from other remotes - some do nothing, but most 'blink' the receiver itself like it read the message... but I've yet to figure out any way to detect these in Windows. Perhaps the receiver 'sees' the signal but can't decode it, perhaps I'm not looking in the right place, I do not know yet. TheGood's Sample 2 (with ALL my 'Other' HID and keyboard registered), AHK's key history, and Girder, did not respond to anything but the original remote signals. My best guess is that it's just using some exotic scan code set (not in Logitech's database) but maybe I can find another set that is within the same range or something...

Unfortunately, there's no way for my Logitech remote to send arbitrarily defined signals or tell me what scan codes it 'learned' from my original remote, but I'll probably try a few more sets of scan codes to see if I can get something else. If anyone has read most of this and has any idea on what I could do to detect those signals (if they even exist!), please do let me know!

Type	SubType	Keyboard Mode	Number of Function Keys	Number of Indicators	Number of Keys Total
81	0	1	12	3	113

Vendor ID	Product ID	Version Number	Usage Page	Usage
1204		256		1		65468		136		'Media Center'
1204		256		1		12		1		Vol +/-


-Thracx

"Man wants to know, and when he ceases to do so, he is no longer a man."
-Fridtjof Nansen

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
Thanks for the details Thracx! It's good to have as much info on as many devices as possible, to help others with the same devices.

I know my receiver blinks as well when I use the TV remote but shows nothing in AHKHID or anywhere. Like you said, I also think it's just that the receiver gets the signal, but can't translate it to anything.

bidomo
  • Members
  • 62 posts
  • Last active: Feb 04 2019 06:30 AM
  • Joined: 05 Feb 2009
Hi everyone!

That's a great script TheGood.

I have some questions too... big story though

I'm using exactly the same kind of hid device as you, the remote is different but operates equally to yours, has some other 3 buttons but I have registered it's hex and dec.

My question is about having more than 1 of those programs running (like in your example MPC and Winamp), I made winamp to respond to global multimedia hotkeys, and even when MPC has the focus, winamp still responds to some of those keypresses...

Let's say MPC, Winamp and VMC (ehshell.exe) are running, if I tell mpc to start playback from the remote, winamp and VMC will do the same if there's something for them to play, but when I tell mpc to stop, VMC will stop too, and winamp will not do till it gets the focus and press stop again.
I know I can change winamp buttons, but problem stills.

This problem persist, even when App Keys in the keyboard are remapped successfully...

I used Intelliremote to control this remote before (don't know if it works in vista x64, but AHK is the way to go for me), but you have to create a profile for each program and stuff. This program required to disable HID service and some other registry keys (but I'm using a phone as HID device too).

By doing that, the USB receiver of the controller (as mentioned before, blinks in almost any remote key press), was able to track the key presses on many other remotes, as TV, Xbox 1 remote, and others, and I was able to get those remotes to work with the PC (only the Xbox1 remote could be useful to me for some other dedicated functions, and the only remote not working is a Nyko Blu-wave remote for Ps3, I think it works more like a game controller than a remote, the Infrared receiver blinks but get's nothing).

Screw Intelliremote, if I can use a free solution with a better and wider support.

The big problem here, is, my 360 remote responses are exactly the same as my HP remote, and that's terrible for thousand reasons...

Is there a way to disable the double keypress the remote does without disabling the phone ?? (my brothers use the phone to control media players from the bathroom, and would like to improve that).

By double press I mean, the one sent with AHK and the default action.

Making a big script for each App I'm gonna use will not be a problem as I want to personalize it so badly.

Note: The input from 360 remote is only different in 7th byte, instead of 04 and 84, it gives F4 and 74

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007

My question is about having more than 1 of those programs running (like in your example MPC and Winamp), I made winamp to respond to global multimedia hotkeys, and even when MPC has the focus, winamp still responds to some of those keypresses...

Let's say MPC, Winamp and VMC (ehshell.exe) are running, if I tell mpc to start playback from the remote, winamp and VMC will do the same if there's something for them to play, but when I tell mpc to stop, VMC will stop too, and winamp will not do till it gets the focus and press stop again.
I know I can change winamp buttons, but problem stills.

Are you using the script to send registered Winamp global hotkeys? Or are you directly controlling Winamp using SendMessage?

The big problem here, is, my 360 remote responses are exactly the same as my HP remote, and that's terrible for thousand reasons...

Do you mean that the data you get from Example 2 are exactly the same? Are those devices in the Other section or the Keyboard section?

Is there a way to disable the double keypress the remote does without disabling the phone ?? (my brothers use the phone to control media players from the bathroom, and would like to improve that).

By double press I mean, the one sent with AHK and the default action.

If I understand correctly (and if you indeed have the same remtoe as mine), it seems like you should uninstall the keyboard driver associated with your receiver, so that only HID messages are received and not keyboard events. I posted them earlier in the thread, but here they are again:

1. Go to Device Manager
2. Expand the "Keyboards" tree
3. You should find a device (ie. your remote registered as a keyboard) other than your usual keyboard there. To make sure it is indeed your remote, you can compare the name you found in Example 1 with the name you'll find when you right-click>Properties>Details on the keyboard item in Device Manager.
4. Once you found the keyboard entry associated to your Kensington Presentation remote, right-click the item and select Uninstall


Also, may I see your script? It'll help me understand what you mean.