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
lukas-riegel
  • Members
  • 2 posts
  • Last active: Jun 04 2009 01:12 PM
  • Joined: 31 May 2009
I´ve got a USB-Numpad.
Is it possible to remap the keys by using this script?
Could someone please give a quick tutorial (or only steps to do and show up)

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

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

I was using Global hotkeys before using your script, I can easily disable them, but the problem will persist in another Media player from M$ or any other using App keys.

The big problem here, is, my 360 remote responses are exactly the same as my HP remote,

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?

The device (USB remote receiver) is the other section, 12/1, 65468/136 and 137, the receiver is the same for both HP remote and 360 remote, the data is identical but 7th byte

Button           Hp Remote        360 Remote
                 6th   7th        6th   7th
Power            0C    84         0C   F4
Vizualization    32    04         32   04

Is there a way to disable the double keypress ...

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

I've done it, but appears to re-install automatically
It has 3 different Keyboard emulation devices.
Disabled all 3 and only the 0-9 keys were disabled.
I'm lost...

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

Haven't changed your script at all, I'm using exactly the same, In the moment I gave it a try, I happened to have MPC, Winamp and VMC running, and the doubts came to my mind.




.::UPDATE::.
Disabled some Registry keys, some Dwords.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HidIr\Remotes\745a17a0-74d3-11d0-b6fe-00a0c90f57da... dd
Deleted:
CodeSetNum1 to CodeSetNum3.

Windows is now unable to use the remote as a Hid Keyboard, the example scripts are working fine, the example 2 script now is able to receive input from any remote and is able to capture it, only drawback, it stills getting input from 360 remote as if it were the HP media center remote...

So, if I want to disable 360 input, 7th byte has to be implemented, right??
Same if I want to use Xbox 1 remote, some of the keys are equal (6th byte) to MCE remote

bidomo
  • Members
  • 62 posts
  • Last active: Feb 04 2019 06:30 AM
  • Joined: 05 Feb 2009
After disabling the remote entries from the registry, I've finally had to add some come (I'm a very bad coder, so any improvement will be appreciated),

The Script is now able to dismiss the 360 remote (compares 6th byte with 04 or 84 values the remote throws randomly, that way the Hp remote will work but 360 remote won't hurt).
At the same time, is able to accept the Xbox1 remote, by comparing 10th byte in the input which totally differs from HP and 360 Remote.

;######################################################################################################################
; FORGET ABOUT MCE REMOTE KEYS!!! THEIR IN THE 1ST PAGE AND YOURS MIGHT BE DIFFERENT ANYWAY...
;######################################################################################################################

;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 EQ") Or WinActive("ahk_class Winamp PE") Or WinActive("ahk_class Winamp Gen")
        sPrefix := "Winamp"
    Else If WinActive("ahk_class MediaPlayerClassicW")
        sPrefix := "MPC"
    Else
    {
        sPrefix  := "Default"
[color=red]
        sPrefix2 := "Default2"  ; Will be Prefix2 to use it exclusively in the Xbox remote 
[/color]
    }
}

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
        [color=red]
        If (NumGet(uData, 6, "UChar") = 132) or (NumGet(uData, 6, "UChar") = 4)   ;; This is how I Dismiss 360 input, comparing 7th byte, count starts in 0
;; HP Remote sends 04 and 84 as 6th byte, 360 sends F4 and 74
[/color]
        {     
            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%
            }    
        }
[color=red]
        else If (NumGet(uData, 9, "UChar") = 24);need to compare to 10th byte of Xbox1 remote 
        ;which is 24 in Dec so the 360 remote will be totally dismissed.

        ;Had to repeat this piece of code, to make it work, and a function will rest me some sleep
        {
            If (iKey <> -1) 
            {
            
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
             
                ;Call the appropriate sub if it exists
                sLabel := sPrefix2 "_" iKey
                If IsLabel(sLabel)
                    Gosub, %sLabel%
            }

        }
[/color]
    }
}

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 {Space}
Return

MPC_24: ;Pause
    SendInput {Space}
Return

MPC_25: ;Stop
    SendInput !s
Return

Winamp_22: ;Play
    SendInput {Media_Play_Pause}
Return
[color=Red]
Default2_25: ;Pause in Xbox1 Remote, just to check the code is working  
    Sendinput 8
[/color]


Any improvement will be highly appreciated.

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

I´ve got a USB-Numpad.
Is it possible to remap the keys by using this script?
Could someone please give a quick tutorial (or only steps to do and show up)


No need for a tutorial, as it's very well explained.
You need to read and re-read 1st and 2nd post, and get as much as you can, that way, you will be able to formulate a much more specific set of questions, if you have to read it 10 times, do it, that way you will get more familiar with this.

AHKHID is a Library to enable your script to get access to Human Interface devices, number 4.- in 2nd post is an actual example of a script using the library.

The example 1-3 are some very useful scripts to get to know how to use your device inside the script.

I know I made a hell of questions, but I was already aware of how to use the script and how to adapt it to my needs (at least I think so).

Follow the rules in the book, and you'll get were you're going in no time...

lukas-riegel
  • Members
  • 2 posts
  • Last active: Jun 04 2009 01:12 PM
  • Joined: 31 May 2009
I fond out that my numpad has the following informations in the keyboard tab:
Name
\\?\HID#VID_04B4&PID_330C#8&2d4bd91d-60&0000#{884b96c3-56ef-11f1-bc-00a8c-00a0c91405dd}
Type
81
Subtype
0
Keyboard Mode
1
Number of Function Keys
12
Number of Indicators
3
Number of Keys Total
113

I tried to uninstall it in the device manager so that it might show up in the other tab. This did not work.

Can someone give me a clue what to do as next?

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

After disabling the remote entries from the registry, I've finally had to add some come
The Script is now able to dismiss the 360 remote (compares 6th byte with 04 or 84 values the remote throws randomly, that way the Hp remote will work but 360 remote won't hurt).
At the same time, is able to accept the Xbox1 remote, by comparing 10th byte in the input which totally differs from HP and 360 Remote.

That's great news! You're a special case because all your devices are using the same receiver, so you can't discriminate on vendor ID and other values. Glad to see you found a way to work it out.

One idea I have, is that you could use have a "multi-prefix" system. The first prefix would be based on the app in the foreground (already implemented that in the prefix loop). The second would be based on which remote device sent it (which would be implemented in the InputMsg() function.

Something like this:

;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 EQ") Or WinActive("ahk_class Winamp PE") Or WinActive("ahk_class Winamp Gen")
        sPrefix := "Winamp"
    Else If WinActive("ahk_class MediaPlayerClassicW")
        sPrefix := "MPC"
    [color=Red]Else sPrefix  := "Default"[/color] ;You don't need the other prefix
}

Return

InputMsg(wParam, lParam)
{
    Local devh, iKey, sLabel, [color=Red]bCallEvent[/color]
   
    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 (NumGet(uData, 6, "UChar") = 132) or (NumGet(uData, 6, "UChar") = 4)
        {   [color=Red];IT'S THE REMOTE[/color]
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
                
                [color=Red]
                ;Set prefix
                sDevicePrefix := "HPRem"
                
                ;We're gonna have to call
                bCallEvent := True
                [/color]
            }
        }
        else If (NumGet(uData, 9, "UChar") = 24)
        {   [color=Red];IT'S THE XBOX1 controller[/color]
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
                [color=Red]
                ;Set prefix
                sDevicePrefix := "XBOX1"
                
                ;We're gonna have to call
                bCallEvent := True
                [/color]
            }
        }
        [color=Red]
        ;Check if we need to call
        If bCallEvent {
            
            ;Call the appropriate sub if it exists
            sLabel := sDevicePrefix "_" sPrefix "_" iKey
            If IsLabel(sLabel)
                Gosub, %sLabel%
            
        }[/color]
    }
}

And then your labels would have names like:

HPRem_VLC_15:
HPRem_VLC_18:
...
XBOX1_VLC_15:
XBOX1_VLC_18:
...

Of course, if you want two buttons on your XBOX and from the HPRem to to do the same thing you can put one on top of the other:

XBOX1_VLC_15:
HPRem_VLC_15:
    ;The code here will be called both when the button with value 15 is pressed on the remote and on the xbox1 controller
Return

Also, crucial question which I don't think you directly answered, does it work? lol
Also, very nice trick with the registry, any link you can share where I could learn more about it?

I tried to uninstall it in the device manager so that it might show up in the other tab. This did not work.


Uninstalling from the device manager is only when your device has a TLC both in the keyboard section AND the Other section, and you don't want it to send keyboard presses automatically. If your device doesn't appear in the Other tab from the beginning, nothing you do can change that. It means the computer sees it as a keyboard, nothing more.

But my guess is that if you want to assign your own code to each key, you don't want the device sending keypresses automatically, right?
If not, have a look at these posts (also read my two replies after his post). The guy had exectly the same dilemma and I offered him some options. See if the script ideas I posted there work.
Let me know if you have a problem. :)

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
Also bimodo, if you're able to see when it's the remote and when it's the XBOX1 controller, then by elimination, you can able find out when it's the XBOX 360 controller. You just have to add another section:

;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 EQ") Or WinActive("ahk_class Winamp PE") Or WinActive("ahk_class Winamp Gen")
        sPrefix := "Winamp"
    Else If WinActive("ahk_class MediaPlayerClassicW")
        sPrefix := "MPC"
    [color=Red]Else sPrefix  := "Default"[/color] ;You don't need the other prefix
}

Return

InputMsg(wParam, lParam)
{
    Local devh, iKey, sLabel, [color=Red]bCallEvent[/color]
   
    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 (NumGet(uData, 6, "UChar") = 132) or (NumGet(uData, 6, "UChar") = 4)
        {   [color=Red];IT'S THE REMOTE[/color]
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
                
                [color=Red]
                ;Set prefix
                sDevicePrefix := "HPRem"
                
                ;We're gonna have to call
                bCallEvent := True
                [/color]
            }
        }
        Else If (NumGet(uData, 6, "UChar") = 244) or (NumGet(uData, 6, "UChar") = 116)
        {   [color=Red];IT'S THE XBOX 360[/color]
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar") ;Just copied this from the other section. You probably have to extract a different byte for the 360 controller
                
                [color=Red]
                ;Set prefix
                sDevicePrefix := "XBOX360"
                
                ;We're gonna have to call
                bCallEvent := True
                [/color]
            }
        }
        Else If (NumGet(uData, 9, "UChar") = 24)
        {   [color=Red];IT'S THE XBOX1 controller[/color]
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
                [color=Red]
                ;Set prefix
                sDevicePrefix := "XBOX1"
                
                ;We're gonna have to call
                bCallEvent := True
                [/color]
            }
        }
        [color=Red]
        ;Check if we need to call
        If bCallEvent {
            
            ;Call the appropriate sub if it exists
            sLabel := sDevicePrefix "_" sPrefix "_" iKey
            If IsLabel(sLabel)
                Gosub, %sLabel%
            
        }[/color]
    }
}


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

One idea I have, is that you could use have a "multi-prefix" system. The first prefix would be based on the app in the foreground (already implemented that in the prefix loop). The second would be based on which remote device sent it (which would be implemented in the InputMsg() function.

Something like this:

;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 EQ") Or WinActive("ahk_class Winamp PE") Or WinActive("ahk_class Winamp Gen")
        sPrefix := "Winamp"
    Else If WinActive("ahk_class MediaPlayerClassicW")
        sPrefix := "MPC"
    [color=Red]Else sPrefix  := "Default"[/color] ;You don't need the other prefix
}

Return

InputMsg(wParam, lParam)
{
    Local devh, iKey, sLabel, [color=Red]bCallEvent[/color]
   
    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 (NumGet(uData, 6, "UChar") = 132) or (NumGet(uData, 6, "UChar") = 4)
        {   [color=Red];IT'S THE REMOTE[/color]
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
                
                [color=Red]
                ;Set prefix
                sDevicePrefix := "HPRem"
                
                ;We're gonna have to call
                bCallEvent := True
                [/color]
            }
        }
        else If (NumGet(uData, 9, "UChar") = 24)
        {   [color=Red];IT'S THE XBOX1 controller[/color]
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
                [color=Red]
                ;Set prefix
                sDevicePrefix := "XBOX1"
                
                ;We're gonna have to call
                bCallEvent := True
                [/color]
            }
        }
        [color=Red]
        ;Check if we need to call
        If bCallEvent {
            
            ;Call the appropriate sub if it exists
            sLabel := sDevicePrefix "_" sPrefix "_" iKey
            If IsLabel(sLabel)
                Gosub, %sLabel%
            
        }[/color]
    }
}

And then your labels would have names like:

HPRem_VLC_15:
HPRem_VLC_18:
...
XBOX1_VLC_15:
XBOX1_VLC_18:
...

That's some more clean and intelligent coding, i'm gonna try it.

Also, crucial question which I don't think you directly answered, does it work? lol

Of course it does!
You can ask someone with an Xbox1 remote (the actual remote for the DVD, not the Media center remote for Xbox1, which I didn't know existed).

Also, very nice trick with the registry, any link you can share where I could learn more about it?

http://blogs.msdn.co.../29/586961.aspx
Talks about many MCE related stuff, includes instructions on how to set the remote ID to work with other remotes, in the other hand, I read it before in TheGreenButton, but they suggested deleting the values and disabling the HID service

Also bimodo, if you're able to see when it's the remote and when it's the XBOX1 controller, then by elimination, you can able find out when it's the XBOX 360 controller.


Yeah, I thought about it, but as I use the 360 remote to play some music while playing, someone may get angry if I skip their songs...

Thanks a lot for your help!

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

One idea I have, is that you could use have a "multi-prefix" system.


;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 EQ") Or WinActive("ahk_class Winamp PE") Or WinActive("ahk_class Winamp Gen")
        sPrefix := "Winamp"
    Else If WinActive("ahk_class MediaPlayerClassicW")
        sPrefix := "MPC"
    Else sPrefix  := "Default" ;You don't need the other prefix
}

Return

InputMsg(wParam, lParam)
{
    Local devh, iKey, sLabel, bCallEvent
   
    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 (NumGet(uData, 6, "UChar") = 132) or (NumGet(uData, 6, "UChar") = 4)
        {   ;IT'S THE REMOTE
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
                
                
                ;Set prefix
                sDevicePrefix := "HPRem"
                
                ;We're gonna have to call
                bCallEvent := True
                
            }
        }
        else If (NumGet(uData, 9, "UChar") = 24)
        {   ;IT'S THE XBOX1 controller
            If (iKey <> -1)
            {
                ;Get keycode (located at the 6th byte)
                iKey := NumGet(uData, 5, "UChar")
                
                ;Set prefix
                sDevicePrefix := "XBOX1"
                
                ;We're gonna have to call
                bCallEvent := True
                
            }
        }
        
        ;Check if we need to call
        If bCallEvent {
            
            ;Call the appropriate sub if it exists
            sLabel := sDevicePrefix "_" sPrefix "_" iKey
            If IsLabel(sLabel)
                Gosub, %sLabel% [color=red]
            else 
            {
                sPrefix  := "Default" 
                sLabel := sDevicePrefix "_" sPrefix "_" iKey
                Gosub, %sLabel%
            }[/color]
        }
    }
}


Already using it, and added some code so if there's and active window from the Prefixes stealing the focus for the remote input, and you press a button which doesn't have a label for that window, will use default prefix, as I'm gonna still use some fixed inputs.

I've been reading here http://msdn.microsof...y/bb417079.aspx, and found the remote is able to send WM_INPUT and WM_APPCOMMANDS, and I would like to know if there's a way to pass some of this events through the script (WM_APPCOMMANDS should be sent straight to windows from what I can Understand)...

When using VMC (which is the only M$ multimedia program I'm gonna use), I would like to keep one of it's features:

Play: Starts playback/resumes from paused/stopped state but won't pause playback, also display/hide the playback OSD, useful when media is subtitled (after restart playback, simply press it again and OSD is gone instantly. WM_APPCOMMAND APPCOMMAND_MEDIA_PLAY
Pause: Will pause playback, nothing else. WM_APPCOMMAND APPCOMMAND_MEDIA_PAUSE

So no APPCOMMAND_MEDIA_PLAY_PAUSE at all...

I've read about SendMessage but can't understand it (maybe need some sleep), and seems to be able to do it

If that's not possible, I would like to send the keyboard equivalents,
and it seems possible to do so even when the app is the backgroud (does not have focus)

I know I'm a pain in the ass, but, can I get some (more) help here???

Some directions and tips can be always useful.

As always, the help will appreciated.

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
I assume you mean WMC (Windows Media Center), right?
Why don't you expand the prefix loop to include the Media Center interface, and then simply send the keys Ctrl+P for Pause and Ctrl+Shift+P for Play (as indicated from the link you posted) ?

If WMC is in the background, then you can use the Default prefix to send your commands. I'm guessing you would first have to check if WMC is indeed running. You can then use ControlSend to send the same keys you would as if they were in the foreground.

Hope this helps! :)

bidomo
  • Members
  • 62 posts
  • Last active: Feb 04 2019 06:30 AM
  • Joined: 05 Feb 2009
I'm checking it and seems to work!

What if I send some virtual keys and scan codes?

I was thinking in making a default prefix, totally different from the rest of the actual prefixes, for other kind of stuff, but some buttons like media center start should keep it's function.

I was thinking in giving the script the ability to lock/unlock to a certain prefix controlled by a hotkey.

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

I'm checking it and seems to work!
What if I send some virtual keys and scan codes?

You can also send custom keycodes with the Send/ControlSend command.
See this.

I was thinking in making a default prefix, totally different from the rest of the actual prefixes, for other kind of stuff, but some buttons like media center start should keep it's function.

I'm not sure I understand what you mean (and not sure if you need help with it). But you can't choose to keep the original functionality for some keys only, unless you find a way to install and uninstall the other HID devices linked to your device on demand. If you had to uninstall a device and as a result lost functionality that you wanted to keep for some keys, you can either re-install the device (at the expense of having less control over the device) or you can try to recreate whatever functionality you lost (which shouldn't be too hard).

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

you can try to recreate whatever functionality you lost (which shouldn't be too hard).


That's what I'm trying, recreate just some of the buttons, the keycodes could be really helpful, but the MCE key (green button) can be recreated easily.

With the help of the keycodes this is gonna be easier.

Thanks a lot.

bidomo
  • Members
  • 62 posts
  • Last active: Feb 04 2019 06:30 AM
  • Joined: 05 Feb 2009
It's me again.

Hope is not offtopic, but I think is not.

There's a way to custimize the keys in the remote, included some info about the way it's been sent to windows (as windows is catching them as keyboard), by doing this, you'll be able to release the buttons you want (to avoid double keys), so they'll be available to use them with the remote script.

You have to modify the RC6MAP.INF file, or create a new one with the info below, don't know if works in vista as I edited the registry directly, and it works.

I've got this info from http://mediacentergu...le_InputINF.pdf

Version]
Signature="$WINDOWS NT$"
[DefaultInstall]
DelReg=Del.Settings
AddReg=Add.Settings
[Del.Settings]
HKLM,"SYSTEM\CurrentControlSet\Services\HidIr\Remotes\745a17a0-74d3-11d0-b6fe-00a0c90f57da","ReportMappingTable"
[Add.Settings]
HKLM,"SYSTEM\CurrentControlSet\Services\HidIr\Remotes\745a17a0-74d3-11d0-b6fe-00a0c90f57da","ReportMappingTable",0x00000001,\

     ;1st to 4th byte is the remote code, 2nd to 4th are all 0x00 in MCE remotes, 360 universal remotes and HP remotes
     ;5th byte is the report method
            ;0x01 Consumer Controls
            ;0x02 MS Vendor Controls
            ;0x03 Standby Button
            ;0x04 Keyboard (key press event)
     ;6th and 7th byte are data which depends on the reporting method
     ;6th will be a modifier key if the reporting method is 0x04, 7th will be the PS/2 scancode.
          ;Bit 0 - no modifier key (0x00)
          ;Bit 1 - CTRL
          ;Bit 2 - SHIFT
          ;Bit 3 - ALT
          ;Bit 4 - WIN Key
          ;CTRL is 1, SHIFT is 2, ALT is 4, and WIN is 8
          ;CTRL 1 (0x01)
          ;SHIFT 2 (0x02)
          ;CTRL+SHIFT 3 (0x03)
          ;ALT 4 (0x04)
          ;CTRL+ALT 5 (0x05)
          ;SHIFT+ALT 6 (0x06)
          ;WIN 8 (0x08)
          ;CTRL+WIN 9 (0x09)
          ;SHIFT+WIN 10 (0x0A)
          ;ALT+WIN 12 (0x0C)

     ;Remove the lines corresponding the keys you want to disable

     0x01,0x00,0x00,0x00, 0x04,0x00,0x1e,  \ ; 1
     0x02,0x00,0x00,0x00, 0x04,0x00,0x1f,  \ ; 2
     0x03,0x00,0x00,0x00, 0x04,0x00,0x20,  \ ; 3
     0x04,0x00,0x00,0x00, 0x04,0x00,0x21,  \ ; 4
     0x05,0x00,0x00,0x00, 0x04,0x00,0x22,  \ ; 5             ;not numpads
     0x06,0x00,0x00,0x00, 0x04,0x00,0x23,  \ ; 6
     0x07,0x00,0x00,0x00, 0x04,0x00,0x24,  \ ; 7
     0x08,0x00,0x00,0x00, 0x04,0x00,0x25,  \ ; 8
     0x09,0x00,0x00,0x00, 0x04,0x00,0x26,  \ ; 9
     0x00,0x00,0x00,0x00, 0x04,0x00,0x27,  \ ; 0
     0x0B,0x00,0x00,0x00, 0x04,0x00,0x28,  \ ; Return
     0x0A,0x00,0x00,0x00, 0x04,0x00,0x29,  \ ; Escape
     0x1D,0x00,0x00,0x00, 0x04,0x02,0x25,  \ ; *   -  SHIFT + 8
     0x1C,0x00,0x00,0x00, 0x04,0x02,0x20,  \ ; #  -   SHIFT + 3
     0x1F,0x00,0x00,0x00, 0x04,0x00,0x51,  \ ; Down arrow
     0x1E,0x00,0x00,0x00, 0x04,0x00,0x52,  \ ; Up arrow
     0x21,0x00,0x00,0x00, 0x04,0x00,0x4f,  \ ; Right arrow
     0x20,0x00,0x00,0x00, 0x04,0x00,0x50,  \ ; Left arrow
     0x22,0x00,0x00,0x00, 0x04,0x00,0x28,  \ ; OK
     0x4E,0x00,0x00,0x00, 0x01,0x08,0x02,  \ ; Print
     0x0F,0x00,0x00,0x00, 0x01,0x09,0x02,  \ ; Properties (Details)
     0x23,0x00,0x00,0x00, 0x01,0x24,0x02,  \ ; Back
     0x16,0x00,0x00,0x00, 0x01,0xb0,0x00,  \ ; Media play
     0x18,0x00,0x00,0x00, 0x01,0xb1,0x00,  \ ; Media pause
     0x17,0x00,0x00,0x00, 0x01,0xb2,0x00,  \ ; Media record <-> Winkey + UP - mute Mic Input (another script)
     0x14,0x00,0x00,0x00, 0x01,0xb3,0x00,  \ ; Media FF
     0x15,0x00,0x00,0x00, 0x01,0xb4,0x00,  \ ; Media RW
     0x1A,0x00,0x00,0x00, 0x01,0xb5,0x00,  \ ; Media next track
     0x1B,0x00,0x00,0x00, 0x01,0xb6,0x00,  \ ; Media previous track
     0x19,0x00,0x00,0x00, 0x01,0xb7,0x00,  \ ; AC Media Stop
     0x10,0x00,0x00,0x00, 0x01,0xe9,0x00,  \ ; volume up
     0x11,0x00,0x00,0x00, 0x01,0xea,0x00,  \ ; volume down
     0x0E,0x00,0x00,0x00, 0x01,0xe2,0x00,  \ ; volume mute
     0x26,0x00,0x00,0x00, 0x01,0x8d,0x00,  \ ; GUIDE
     0x12,0x00,0x00,0x00, 0x01,0x9c,0x00,  \ ; Channel up
     0x13,0x00,0x00,0x00, 0x01,0x9d,0x00,  \ ; Channel down
     0x32,0x00,0x00,0x00, 0x00,0x00,0x00,  \ ; Vizualization             ---
     0x33,0x00,0x00,0x00, 0x00,0x00,0x00,  \ ; Slide show                ---
     0x34,0x00,0x00,0x00, 0x00,0x00,0x00,  \ ; Eject <-> Winkey +Down - Mute Line In
     0x0C,0x00,0x00,0x00, 0x03,0x82,0x00   \ ; Suspend

;this buttons and codes are omitted, they're not negotiable while using the remote with the default settings:
;Radio, Music, Pictures, Videos, MCE Start, DVD Menu, LiveTV, Aspect, RecordedTV, GUIDE
;Search for info in how to disable the remote and personalize it 


How I wish AHK had {Media_Play} and {Media_Pause}, that way I would be able to totally rely on the remote script + AHKHID.


.::Edit::. Forgot to say...

You have to fill with 00 the rest of the bytes on each key you want to disable in the main remote driver, just make sure the keycode exist, like this:
0x32,0x00,0x00,0x00, 0x00,0x00,0x00, \ ; Visualization
0x33,0x00,0x00,0x00, 0x00,0x00,0x00, \ ; Slide show

If you choose to do it through the registry, the keys will show like this, so take care:
Just remember, each button has a 7 bytes code so don't let the 8 byte confuse you.
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,00,

in a .reg file (the easier way to edit the keys, will look like this:
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HidIr\Remotes\745a17a0-74d3-11d0-b6fe-00a0c90f57da]
"ReportMappingTable"=hex: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,00,00,00,00,00,\
    00,00,0b,00,00,00,04,08,58,0a,00,00,00,04,00,29,1f,00,00,00,04,00,51,1e,00,\
    00,00,04,00,52,21,00,00,00,04,00,4f,20,00,00,00,04,00,50,22,00,00,00,04,00,\
    28,4e,00,00,00,04,08,45,0f,00,00,00,01,09,02,23,00,00,00,01,24,02,16,00,00,\
    00,01,b0,00,18,00,00,00,01,b1,00,17,00,00,00,04,08,52,14,00,00,00,01,b3,00,\
    15,00,00,00,01,b4,00,1a,00,00,00,01,b5,00,1b,00,00,00,01,b6,00,19,00,00,00,\
    01,b7,00,6e,00,00,00,01,cd,00,10,00,00,00,01,e9,00,11,00,00,00,01,ea,00,0e,\
    00,00,00,01,e2,00,26,00,00,00,01,8d,00,12,00,00,00,01,9c,00,13,00,00,00,01,\
    9d,00,0c,00,00,00,04,09,2b,2a,00,00,00,03,82,00,34,00,00,00,04,08,51,1c,00,\
    00,00,04,08,58,
"CodeSetNum0"=dword:00000001
"CodeSetNum1"=dword:00000002
"CodeSetNum2"=dword:00000003
"CodeSetNum3"=dword:00000004


Just keep in mind, the next list of buttons are not negotiable unless you disable the ehtray.exe process(and maybe other, I don't remember):
Radio, Music, Pictures, Videos, MCE Start, DVD Menu, LiveTV, Aspect, RecordedTV, GUIDE

This is for the Hp Media center remote, which, from my point of view, is the best of all, and the 360 remote as second place, they have much more negotiable keys to start with.

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

I'm not sure if you realize it or not, but what you just found is astounding! To know that we can do this changes everything! (I'm not only talking about your case, but AHKHID in general). I'm still going through the details, but it looks very promising indeed.

As for your question, the reason AHK doesn't have MEDIA_PLAY and MEDIA_PAUSE is because there is no such virtual keycode for these actions. The only media-related keycodes are VK_MEDIA_NEXT_TRACK (0xB0), VK_MEDIA_PLAY_PAUSE (0xB3), VK_MEDIA_PREV_TRACK (0xB1) and VK_MEDIA_STOP (0xB2). Your best bet is to have a PLAY and PAUSE action dependent on the program (for example with Winamp, you can use SendMessage for this).

Again, thanks for posting what you found! :D