AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

AHKHID - An AHK implementation of the HID functions
Goto page 1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
TheGood



Joined: 30 Jul 2007
Posts: 399

PostPosted: Thu Feb 26, 2009 1:45 am    Post subject: AHKHID - An AHK implementation of the HID functions Reply with quote

Download

Examples on how to use it:
Example 1 allows you to look at all the HID devices currently connected to your computer.
Example 2 allows you to register devices and examine the data coming out.
Example 3 is an example on how to detect mouse events, such as left mouse button up, wheel down, etc...

Documentation (also included in AHKHID.ahk)
Let me know if the webpage doesn't look right to you. I know next to nothing in HTML and had to learn through trial-and-error in order to build that page.

How do I stop the default keypresses coming out of my device?
This is a question that has been asked often enough to warrant answering it on the main post. AHKHID cannot stop a device's default keypresses from generating. This functionality is not part of the raw input device interface that AHKHID wraps.

If you need to disable those default keypresses, you have three options, depending on which category you fit in:
  • If the device shows up as a remote, you can easily disable/modify the keys sent by modying the registry. For more information on this technique, see Step 5 of the tutorial posted below (second post in this thread).
  • If it does not show up as a remote, but does show up in the Other tab whose TLC when registered allows you to capture all the keys, then you can try uninstalling the keyboard. For more information on this technique, see here.
  • If it does not show up as a remote or as a device in the Other tab, but as a keyboard only, then you can try registering the keyboard TLC (UsPg 1 and Us 6) and filter the relevant keypresses. Look here for a sample script on how to do that. Don't look at the second method described in that post, it does not work.
If you somehow don't fit in any of these categories, then make a post and I'll see if there might be another way.

Extreme method: Disabling all simulated keypress events
This is another method which will disable all simulated keypresses (from devices, as well as from the Send command), but allow the physical keypresses to go through. It obviously has a huge drawback, but it's there if you really need it.

Code:
/*
    This approach allows you to let through physical b presses while denying simulated presses. You can obviously
    change it to whichever key you wish to filter. It requires a bit of explanation. We can't use the keyboard
    hook, because otherwise simulated presses will not be caught. But we need to retrieve the physical state of
    the buttons, which can't be done with GetKeyState() if the keyboard hook is not installed. This is why we have
    to use the API directly. To not catch the simulated keypress sent here, we have to turn off the hotkey itself
    before.
   
    The problem with this method is that it will block ALL simulated b presses, not only the ones coming from
    remotes.
   
    The virtual-key code for b is 0x42. The VK code for other keys can be found at:
    http://msdn.microsoft.com/en-us/library/ms645540.aspx
   
    To test: physically pressing b will produce b, but pressing a, which sends a simulated b, will be blocked.
*/

b::
    If (DllCall("GetAsyncKeyState", "int", 0x42, "ushort") >> 15) {
        Hotkey, b,, Off
        SendInput, b
        Hotkey, b,, On
    }
Return

a::SendInput, b


Acknowledgements:Thank you all for the help!

As always, comments and suggestions are welcome. As well as trouble with registering that one button on your keyboard. Very Happy
Enjoy!

Screenshots of each example in action:




Changelog

March 5, 2010

- Updated the naming convention to allow for integration in library
- Hardcoded the constants into the functions
- Added clear on double-click in Example 2
- Added copy device name on double-click in Example 1

April 29, 2009

- Updated functions so that they use ErrorLevel instead of a MsgBox upon error.
- Clarified documentation so that return values are clearer to understand.

April 8, 2009

- Removed functions' dependance on constants. This means that you don't have to put the #Include line in the auto-execute section anymore if you don't want to initialize the constants.


Last edited by TheGood on Sat Mar 06, 2010 11:15 pm; edited 4 times in total
Back to top
View user's profile Send private message Visit poster's website
TheGood



Joined: 30 Jul 2007
Posts: 399

PostPosted: Thu Apr 09, 2009 12:53 am    Post subject: Reply with quote

Tutorial

Here is a real life example of how to use AHKHID.
When I bought my HP Media Center a few years ago, I also received this nice remote with a receiver which connects through USB. The remote is meant to be used with the Media Center interface.



However, I eventually changed computer but still had the remote. So, I started wondering if I could find a way to detect all the button presses and assign labels to each of them. Although some of them triggered keyboard events (like the arrow buttons, the numbers, the OK button and the volume up/down button), I had no way of knowing if it came from the remote or from the keyboard.

So, these are the steps I used (and the steps you can use for any other HID device).

1. Figuring out the device specs

First thing I had to figure out was to get the Vendor ID, Product ID, Version Number, and most importantly, the Usage Page and Usage the remote operates on. To do this, I fired up Example 1 and looked at the "Other" tab. The following picture is a screenshot of what I saw. In red are the "devices" registered to the remote (I know this because they only appeared after I plugged in the receiver).




As you can see, the three devices are from the remote. However, they all operate on a different Usage Page and/or Usage. Anyways, at least now I know what the Vendor ID, the Product ID and the Version Number are (which will be needed later on in the script in order to make sure the input comes from the remote).

2. Reverse engineering the data

So now that I know on which Usage Page/Usage the remote operates on, I can fire up Example 2 and look at the data coming out of it. However, since the remote possesses three different TLCs (TLC means the Usage Page and Usage values), I had to register the three of them. Also, I modified Example 2 so that the output also shows the Usage Page/Usage values from which the data came from (so that I can distinguish between the three). Then, I clicked the Call button and started pressing buttons.



This is the part where I had to "reverse engineer" the data. I realized that
  • The TLC with UsPg 65468 and Us 136 showed down and up events only for some buttons.
  • Similarly, the TLC with UsPg 12 and Us 1 showed down and up events only for some (other) buttons.
  • Together, those two TLCs did not cover all the buttons.
  • And most importantly, the TLC with UsPg 65468 and Us 137 showed an event for every button pressed, but only on the down event.

3. Collecting data

I decided to therefore concentrate on the last TLC (the one with UsPg 65468 and Us 137) because it was the only one with access to all buttons and because I didn't really need the Up event. However, I obviously could have decided to support as many buttons with up/down events, but I just felt it would have been extra work for not much (for what I wanted to do with it).

So now, I had to make a list of the data received for each button press. I therefore created a nice spreadsheet where I typed out the name of all the buttons. I then modified Example 2 so that instead of adding data to the listbox, it would simply do SendInput % Bin2Hex(&uData, r) "{Enter}"
which means it would insert the data (in hex format) in the cell and then press Enter to go to the next cell. This is what I got:



As you can see, I noticed that the only thing that changed for each press was the value of the 6th byte (the 7th byte is also different, but it only alternates between 04 and 84, no matter the buttons pressed).

4. Creating a script

All I had left do to was to create a simple script which would register the remote and check the 6th byte on input to see which button was pressed. The goal of the script was to add remote functionality to VLC and MPC (Media Player Classic). Instead of creating a label for each button, I decided to create labels only when needed, such that the OnMessage function only had to check if the label existed before calling it. I also added a prefix to the label, such that the label to be called would depend on the program currently in focus. For example, if VLC is in focus, the prefix would be "VLC" such that when you press the button with value 22 (which is Play), the OnMessage function will call the label called VLC_22 (if it exists). This is the resulting script:

Code:
/*!

DVD Menu                36
Power                   12
TV                      70
Radio                   80
Music                   71
Pictures                73
Videos                  74
Record                  23
Rewind                  21
Replay/Previous Track   27
Play                    22
Pause                   24
Stop                    25
Forward                 20
Skip/Next Track         26
Back                    35
More/Information        15
Up Arrow                30
Left Arrow              32
Right Arrow             33
Down Arrow              31
OK                      34
Volume Up               16
Volume Down             17
Windows Media Center    13
Mute                    14
Channel/Page Up         18
Channel/Page Down       19
Live TV                 37
Guide                   38
Recorded TV             72
1                       1
2/ABC                   2
3/DEF                   3
4/GHI                   4
5/JKL                   5
6/MNO                   6
7/PQRS                  7
8/TUV                   8
9/WXYZ                  9
*                       29
0                       0
#                       28
Clear                   10
Print                   78
Enter                   11

*/

;Must be in auto-execute section if I want to use the constants
#Include %A_ScriptDir%\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 := HID_Register(65468, 137, hGui, RIDEV_INPUTSINK)

;Prefix loop
Loop {
    Sleep 1000
    If WinActive("ahk_class QWidget") Or WinActive("ahk_class VLC DirectX")
        sPrefix := "VLC"
    Else If WinActive("ahk_class Winamp v1.x") Or WinActive("ahk_class Winamp Video")
        sPrefix := "Winamp"
    Else If WinActive("ahk_class MediaPlayerClassicW")
        sPrefix := "MPC"
    Else sPrefix := "Default"
}

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 my HP remote
        And (HID_GetDevInfo(devh, DI_DEVTYPE, True) = RIM_TYPEHID)
        And (HID_GetDevInfo(devh, DI_HID_VENDORID, True) = 1118)
        And (HID_GetDevInfo(devh, DI_HID_PRODUCTID, True) = 109)
        And (HID_GetDevInfo(devh, DI_HID_VERSIONNUMBER, True) = 272) {
       
        ;Get data
        iKey := HID_GetInputData(lParam, uData)
       
        ;Check for error
        If (iKey <> -1) {
           
            ;Get keycode (located at the 6th byte)
            iKey := NumGet(uData, 5, "UChar")
           
            ;Call the appropriate sub if it exists
            sLabel := sPrefix "_" iKey
            If IsLabel(sLabel)
                Gosub, %sLabel%
        }
    }
}

VLC_15: ;More
    SendInput f ;Toggle fullscreen
Return

VLC_18: ;Channel Up
    SendInput ^{Up}
Return

VLC_19: ;Channel Down
    SendInput ^{Down}
Return

VLC_21: ;Rewind
    SendInput !{Left}
Return

VLC_27: ;Previous Track
    SendInput p
Return

VLC_22: ;Play
    SendInput q
Return

VLC_24: ;Pause
    SendInput {Space}
Return

VLC_25: ;Stop
    SendInput s
Return

VLC_20: ;Forward
    SendInput !{Right}
Return

VLC_26: ;Next Track
    SendInput n
Return

MPC_15: ;More
    SendInput !{Enter} ;Toggle fullscreen
Return

MPC_18: ;Channel Up
    SendInput {Up}
Return

MPC_19: ;Channel Down
    SendInput {Down}
Return

MPC_21: ;Rewind
    SendInput !{Left}
Return

MPC_20: ;Forward
    SendInput !{Right}
Return

MPC_27: ;Previous Track
    SendInput !{End}
Return

MPC_26: ;Next Track
    SendInput !{Home}
Return

MPC_22: ;Play
    SendInput !p
Return

MPC_24: ;Pause
    SendInput {Space}
Return

MPC_25: ;Stop
    SendInput !s
Return


Extra: 5. Disabling/modifying original key functions

A lot of the buttons on my remote generated events when pressed. Some were keyboard events (e.g. the numbers 0 to 9 produced their respective numbers), and some were more advanced events (e.g. the power button would send the computer in standby). I wanted to disable these events so that they would not conflict with the new functions I've given the buttons. The user bidomo here showed us a way on exactly how to do that, and I will just run through that methods here. Note that you can also use this method to modify or create the default action of each key, without using AHKHID.

You first have to navigate in the registry to the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HidIr\Remotes\745a17a0-74d3-11d0-b6fe-00a0c90f57da. If your remote does not produce that key, then the following will not work. You might have other keys in that same Remotes key but as far as I understand, you cannot work with them. You can only work with the ones whose RemoteName value is RC6 based MCE remote.

Now, export that key (right-click the key, select Export, and save the file somewhere). The only value we'll modify is the ReportMappingTable value. Therefore, you can erase all the other sections contained in the file. Mine looks like this (after doing some formatting so that 7 digits were on each line):

Code:
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HidIr\Remotes\745a17a0-74d3-11d0-b6fe-00a0c90f57da]
"ReportMappingTable"=hex:\
    00,00,00,00,04,00,27,\
    01,00,00,00,04,00,1e,\
    02,00,00,00,04,00,1f,\
    03,00,00,00,04,00,20,\
    04,00,00,00,04,00,21,\
    05,00,00,00,04,00,22,\
    06,00,00,00,04,00,23,\
    07,00,00,00,04,00,24,\
    08,00,00,00,04,00,25,\
    09,00,00,00,04,00,26,\
    0a,00,00,00,04,00,29,\
    0b,00,00,00,04,00,28,\
    0c,00,00,00,03,82,00,\
    0e,00,00,00,01,e2,00,\
    0f,00,00,00,01,09,02,\
    10,00,00,00,01,e9,00,\
    11,00,00,00,01,ea,00,\
    12,00,00,00,01,9c,00,\
    13,00,00,00,01,9d,00,\
    14,00,00,00,01,b3,00,\
    15,00,00,00,01,b4,00,\
    16,00,00,00,01,b0,00,\
    17,00,00,00,01,b2,00,\
    18,00,00,00,01,b1,00,\
    19,00,00,00,01,b7,00,\
    1a,00,00,00,01,b5,00,\
    1b,00,00,00,01,b6,00,\
    1c,00,00,00,04,02,20,\
    1d,00,00,00,04,02,25,\
    1e,00,00,00,04,00,52,\
    1f,00,00,00,04,00,51,\
    20,00,00,00,04,00,50,\
    21,00,00,00,04,00,4f,\
    22,00,00,00,04,00,28,\
    23,00,00,00,01,24,02,\
    26,00,00,00,01,8d,00,\
    4e,00,00,00,01,08,02


I also sorted the lines, so that the first digit of each line went from smallest to largest. Before modifying any values, make a backup of this file (in case you want to restore the original key functions) and open the copy you wish to modify in a text editor. It might help you to do the same thing I did and separate the lines after every 7th digit.

Each line (or each consecutive 7 digits) represent a button and the default action associated with that button. To understand in details how it works, please read the PDF file to which bidomo linked in his post. The most important digit is the first one, as it tells you which key of the remote is associated with the following action (the following digits). For example, in the file I posted above, you can see that one of the lines is "0b,00,00,00,04,00,28". The digit 0b is the code representing the Enter button on my remote. How do I know this? There are two ways: you can either look at the PDF file, which will most likely tell you the correct value for each key on your remote, or, if you did Step 3, you can use the data there to know for sure which key on your remote is which line in the registry. For example, 0b in decimal is 11 which is, as reported in Step 3, the Enter key.

The advantage with the second method is that you will know exactly which button on your remote refers to which line in the registry. Also, the PDF file doesn't list all the keys. And most importantly, if your goal is to assign new events to each button, it's important for you to know that not all your remote buttons are described in ReportMappingTable. Therefore, using the keycode found in Step 3, you can create new lines for buttons which don't yet have a given function in the table. An example of this in my case are the DVD Menu and Live TV buttons, which have a keycode of 24, and 25 (in hex), which as you can see, are not in the original ReportMappingTable.

If your goal is to simply disable ALL the orignal events of your keys, you simply have to replace all the digits that follow keycodes by 00, like this:

Code:
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HidIr\Remotes\745a17a0-74d3-11d0-b6fe-00a0c90f57da]
"ReportMappingTable"=hex:\
    00,00,00,00,00,00,00,\
    01,00,00,00,00,00,00,\
    02,00,00,00,00,00,00,\
    03,00,00,00,00,00,00,\
    04,00,00,00,00,00,00,\
    05,00,00,00,00,00,00,\
    06,00,00,00,00,00,00,\
    07,00,00,00,00,00,00,\
    08,00,00,00,00,00,00,\
    09,00,00,00,00,00,00,\
    0A,00,00,00,00,00,00,\
    0B,00,00,00,00,00,00,\
    0C,00,00,00,00,00,00,\
    0D,00,00,00,00,00,00,\
    0E,00,00,00,00,00,00,\
    0F,00,00,00,00,00,00,\
    10,00,00,00,00,00,00,\
    11,00,00,00,00,00,00,\
    12,00,00,00,00,00,00,\
    13,00,00,00,00,00,00,\
    14,00,00,00,00,00,00,\
    15,00,00,00,00,00,00,\
    16,00,00,00,00,00,00,\
    17,00,00,00,00,00,00,\
    18,00,00,00,00,00,00,\
    19,00,00,00,00,00,00,\
    1A,00,00,00,00,00,00,\
    1B,00,00,00,00,00,00,\
    1C,00,00,00,00,00,00,\
    1D,00,00,00,00,00,00,\
    1E,00,00,00,00,00,00,\
    1F,00,00,00,00,00,00,\
    20,00,00,00,00,00,00,\
    21,00,00,00,00,00,00,\
    22,00,00,00,00,00,00,\
    23,00,00,00,00,00,00,\
    24,00,00,00,00,00,00,\
    25,00,00,00,00,00,00,\
    26,00,00,00,00,00,00,\
    46,00,00,00,00,00,00,\
    47,00,00,00,00,00,00,\
    48,00,00,00,00,00,00,\
    49,00,00,00,00,00,00,\
    4A,00,00,00,00,00,00,\
    4E,00,00,00,00,00,00,\
    50,00,00,00,00,00,00


And there you go. This is how to modify/disable the original function of your remote's buttons. This could, in theory, allow you to completely bypass the need for AHKHID by assigning key combinations to each remote button and catching those hotkeys in a regular AHK script.

Here's more reading material on the subject:

All About Media Center Remotes (advanced) - source of the informative PDF
Archive: Key Support, Keyboard Scan Codes, and Windows - information about HID Usage ID (needed to assign a certain keyboard event to a remote button)

Hope this helps!


Last edited by TheGood on Sat Mar 06, 2010 6:49 am; edited 5 times in total
Back to top
View user's profile Send private message Visit poster's website
k3ph



Joined: 21 Jul 2006
Posts: 221

PostPosted: Thu Apr 09, 2009 1:48 am    Post subject: Reply with quote

wow, awesome! this is a must have tool!
this really should be included in the official installation pack!!!

i loved the vlc/mpc stuff, great idea!

thanks for sharing it, wonderful work
when i get time, i'll test it with more different devices :D maybe i can ressurrect some old stuff here...
_________________
                                  [ profile | ahk.net | ahk.talk ]
Back to top
View user's profile Send private message Send e-mail
TheGood



Joined: 30 Jul 2007
Posts: 399

PostPosted: Fri Apr 10, 2009 4:24 am    Post subject: Reply with quote

I'm glad you like it! Very Happy
Definitely come back if you have any problems with your HID devices!
Back to top
View user's profile Send private message Visit poster's website
b0ring



Joined: 23 Apr 2009
Posts: 2

PostPosted: Thu Apr 23, 2009 10:16 am    Post subject: Reply with quote

Firstly, a huge thanks for creating this especially since I'm running 64bit so AutoHotkeyRemoteControlDLL didn't work, and Girder hasn't seemed to work with HID since version 3.

I had to rejig your code a little to get it to work with my remote, it seems to be running fine but I'd like a little feedback on how I've set it up since I'm a complete newbie to autohotkey.

When running Example 2 to catch the data, mine is in the format "Data: 040002"; "Data: 040040"; etc. My code is as follows...

Code:

;Must be in auto-execute section if I want to use the constants
#Include %A_ScriptDir%\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 := HID_Register(65468, 136, hGui, RIDEV_INPUTSINK)
p := HID_Register(12, 1, hGui, RIDEV_INPUTSINK)

Return

InputMsg(wParam, lParam) {
    Local devh, iKey, sLabel
   
    Critical
   
    ;Get handle of device
    devh := HID_GetInputInfo(lParam, II_DEVHANDLE)
   
    ;Check that it is my HP remote
    If (HID_GetDevInfo(devh, DI_DEVTYPE, True) = RIM_TYPEHID)
        And (HID_GetDevInfo(devh, DI_HID_VENDORID, True) = 1894)
        And (HID_GetDevInfo(devh, DI_HID_PRODUCTID, True) = 516)
   And (HID_GetDevInfo(devh, DI_HID_VERSIONNUMBER, True) = 1) {
       
        ;Get data
        HID_GetInputData(lParam, uData)   
   iKey := NumGet(uData, 0, "UInt")
   sLabel := "RC_" . iKey
   if IsLabel(sLabel)
      Gosub, %sLabel%
    }
}

;Home
RC_260:
Return

;Red
RC_32772:
   Run "C:\Program Files (x86)\CyberLink\PowerDVD\PowerDVD.exe"
Return

;Green
RC_2052:
Return

;Yellow
RC_4100:
Return

;Blue
RC_8196:
   Run "C:\Program Files (x86)\XBMC\XBMC.exe" -fs -p
Return

...


I played around on variations of the "NumGet(uData, 5, "UChar")" in your code but the only way I could find unique numbers was using "NumGet(uData, 0, "UInt")" but these differ largely from the data reported back in Example 2, such as the blue button having an 8196 code instead of the reported data of 042000. Do you know if this a reliable and safe way of capturing the buttons, since it seems to work perfectly?
Back to top
View user's profile Send private message
TheGood



Joined: 30 Jul 2007
Posts: 399

PostPosted: Thu Apr 23, 2009 1:25 pm    Post subject: Reply with quote

OK, I have to go to work right. But I'll give you a more detailed response tonight.

All I can tell you for now, is to make a complete list of the data coming in for each button (like I did in Step 3). In my case, only one byte was different, the 6th one, hence the NumGet(uData, 5, "UChar"). It might be different in your case (if one byte is not enough to differentiate between buttons).

The example script I posted is really just an example. It's very device-specific in many ways. I'll try making a script "template" to help guide you.
Back to top
View user's profile Send private message Visit poster's website
n-l-i-d
Guest





PostPosted: Fri Apr 24, 2009 3:11 am    Post subject: Reply with quote

Very good stuff! Cool
Back to top
TheGood



Joined: 30 Jul 2007
Posts: 399

PostPosted: Fri Apr 24, 2009 3:56 am    Post subject: Reply with quote

b0ring wrote:
I had to rejig your code a little to get it to work with my remote, it seems to be running fine but I'd like a little feedback on how I've set it up since I'm a complete newbie to autohotkey.

The script looks fine. However, I have a question. Do you actually need to register the TLC with Usage Page 65468 and Usage 136 ? Or is that just left-over from my script? Because the reason it's there in my script is because that's the TLC my remote uses. But unless yours does as well, you don't have to register it.

b0ring wrote:
I played around on variations of the "NumGet(uData, 5, "UChar")" in your code but the only way I could find unique numbers was using "NumGet(uData, 0, "UInt")" but these differ largely from the data reported back in Example 2, such as the blue button having an 8196 code instead of the reported data of 042000. Do you know if this a reliable and safe way of capturing the buttons, since it seems to work perfectly?

Don't forget that the data coming out of Example 2 is in hexadecimal. When you use NumGet, you're using its decimal value. This might explain the discrepancy between the two reported data (8196 in hex is 2004 which is what Example 2 gave, except the bytes go from left to right instead of right to left, ie. the leftmost byte is the first byte). What you could do is to modify Example 2 so that it gives out the decimal

n-l-i-d wrote:
Very good stuff! Cool

Thanks!
Back to top
View user's profile Send private message Visit poster's website
b0ring



Joined: 23 Apr 2009
Posts: 2

PostPosted: Fri Apr 24, 2009 8:59 am    Post subject: Reply with quote

TheGood wrote:
Do you actually need to register the TLC with Usage Page 65468 and Usage 136 ? Or is that just left-over from my script?


The bulk of my remote buttons were on 65468 and 136 with a few extra ones on 12 and 1, so I did need both.

TheGood wrote:
Don't forget that the data coming out of Example 2 is in hexadecimal. When you use NumGet, you're using its decimal value. This might explain the discrepancy between the two reported data (8196 in hex is 2004 which is what Example 2 gave, except the bytes go from left to right instead of right to left, ie. the leftmost byte is the first byte). What you could do is to modify Example 2 so that it gives out the decimal


Ah, okay. My main concern was just that I didn't know where these numbers were coming from or how they were represented, but if mine are using the same values but just in a different format that's fine by me. Just so long as it works and won't explode later on.

Thanks again for the script and this very efficient and helpful support. Very Happy
Back to top
View user's profile Send private message
LarryD
Guest





PostPosted: Sat Apr 25, 2009 7:08 pm    Post subject: Reply with quote

First of all thank You for the great script!!!
I succesfully tested it on Windows 7 x64.

Is it possible somehow to repeat the generated keypresses (SendInput) if the user holds the remote button pressed for a longer time?
Back to top
TheGood



Joined: 30 Jul 2007
Posts: 399

PostPosted: Sat Apr 25, 2009 8:15 pm    Post subject: Reply with quote

LarryD wrote:
First of all thank You for the great script!!!
I succesfully tested it on Windows 7 x64.

That's great to hear, seeing as I only have XP to test with. Very Happy

LarryD wrote:
Is it possible somehow to repeat the generated keypresses (SendInput) if the user holds the remote button pressed for a longer time?

Yes, of course. As long as you have a way of knowing when the remote button is pressed down, and when it is pressed up (as you saw in the example I gave, for my script, I chose to discard the Up events).

There are multiple ways of doing it I'm sure, but one I can think of is to rig the Down event to a sub that starts a timer (which will repeat the SendInputs) and rig the Up event to a sub which disables the timer. Something like this (pseudocode - showing only the relevant parts):

Code:
InputMsg(wParam, lParam) {
   
    ;...
   
    ;Get the keycode
    iKey := NumGet(uData, 5, "UChar")
   
    If bDownEvent
        Gosub, KeyIsDown
    Else Gosub, KeyIsUp
}

KeyIsDown:
    SetTimer, MyTimer, 200 ;Set the interval here (ie. if you want faster repetitions while the key is down, you would put a smaller number)
    Gosub, MyTimer ;So that it starts the first keypress right away
Return

KeyIsUp:
    SetTimer, MyTimer, Off
Return

MyTimer:
    SendInput, The key is still down{!}
Return


Of course, you can easily modify the idea using the method I used to do this for multiple keys (by using dynamic labels). You'll also have to modify the algorithm if you want the keypresses to be sent every (say) 200 ms. only after the key has been down for (say) 500 ms. (to simulate the behaviour of keyboard key presses).

Let me know if you need more guidance. Smile
Back to top
View user's profile Send private message Visit poster's website
LarryD
Guest





PostPosted: Sun Apr 26, 2009 12:50 pm    Post subject: Reply with quote

Thank you for the quick replay!
Unfortunately I can detect just one event, the down event.
I'm trying to use an MCE remote (UsPg 65468 and Us 137).
Any ideas? Maybe reading multiple times with HID_GetInputData?
Back to top
TheGood



Joined: 30 Jul 2007
Posts: 399

PostPosted: Sun Apr 26, 2009 3:45 pm    Post subject: Reply with quote

Unfortunately, there's no way around it. If you don't have an Up event, you can't know when the button is released, and therefore you can't know when to stop repeating the keypresses.

I find it surprising that your MCE remote doesn't send an Up event. Is it the same model as mine? Did you test the buttons under all registered TLCs? Don't forget also that the Up event is not necessarily on the same TLC as the Down event.
Back to top
View user's profile Send private message Visit poster's website
Micha



Joined: 15 Nov 2005
Posts: 500
Location: Germany

PostPosted: Tue Apr 28, 2009 11:29 am    Post subject: Reply with quote

Hi,
thanks for the script.
At my post (DLLCall: Support for Human Interface devices) I put a link to your solution.
I hope you'll continue developing it.
Ciao
Micha
Back to top
View user's profile Send private message
TheGood



Joined: 30 Jul 2007
Posts: 399

PostPosted: Thu Apr 30, 2009 12:27 am    Post subject: Reply with quote

Thank you Micha! I really appreciate the link. Very Happy

I made little updates:
Changelog wrote:
- Updated functions so that they use ErrorLevel instead of a MsgBox upon error.
- Clarified documentation so that return values are clearer to understand.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
Page 1 of 10

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group