boogieoompa Posted July 31, 2009 Share Posted July 31, 2009 I am trying to write a script that will interface a HID (human interface device) into my PC by translating its functions. For example if a user presses the upper right button the device sends "page up". My goal was to write a script that effectivly says "this input came from device x change page up to shift5". For the most part this code works but since a rather elaborate function needs to be run on every input often times you have to press the key 2-3 times for it to work. Any ideas on how to make this more effecient? At the moment I decided to use HotKeySets since I did not know another way of stopping input (aka stopping the HID from registering the key stroke)while a function ran. This code is a VERY slightly modified version of one posted from Authenticity from this thread [link]http://www.autoitscript.com/forum/index.php?showtopic=95105[/link]. As always any help would be appreciated. expandcollapse popup#include <RawInput.au3> HotKeySet('{ESC}', '_EXIT') HotKeySet("a", "USB_C") Global $tRID_KD, $pRID_KD, $iRID_KD Global $tRIH, $pRIH, $iRIH Global $iNumDevices Global $hGUI , $pData Global $USB Global $Paused $hGUI = GUICreate('Test', 100, 100) GUIRegisterMsg($WM_INPUT, 'OnInput') $tRID_KD = DllStructCreate($tagRAWINPUTDEVICE) $pRID_KD = DllStructGetPtr($tRID_KD) $iRID_KD = DllStructGetSize($tRID_KD) $tRIH = DllStructCreate($tagRAWINPUTHEADER) $pRIH = DllStructGetPtr($tRIH) $iRIH = DllStructGetSize($tRIH) $iNumDevices = 1 DllStructSetData($tRID_KD, 'usUsagePage', 0x01) DllStructSetData($tRID_KD, 'usUsage', 0x06) DllStructSetData($tRID_KD, 'dwFlags', BitOR($RIDEV_NOLEGACY, $RIDEV_INPUTSINK)) DllStructSetData($tRID_KD, 'hwndTarget', $hGUI) _RegisterRawInputDevices($pRID_KD, $iNumDevices, $iRID_KD) While 1 Sleep(100) WEnd Func USB_C() If $USB = 1 Then Send ( "t" ) $USB = 0 EndIf EndFunc Func OnInput($hwnd, $iMsg, $iwParam, $ilParam) Local $tRI_KD, $pRI_KD, $iRI_KB Local $tRIDI_HID, $pRIDI_HID, $iRIDI_HID Local $hDevice $tRI_KD = DllStructCreate($tagRAWINPUT_KEYBOARD) $pRI_KD = DllStructGetPtr($tRI_KD) $iRI_KB = DllStructGetSize($tRI_KD) $tRIDI_HID = DllStructCreate($tagRIDDEVICEINFO_HID) $pRIDI_HID = DllStructGetPtr($tRIDI_HID) $iRIDI_HID = DllStructGetSize($tRIDI_HID) DllStructSetData($tRIDI_HID, 'cbSize', $iRIDI_HID) _GetRawInputData($ilParam, $RID_INPUT, $pRI_KD, $iRI_KB, $iRIH) If Not @error Then $hDevice = DllStructGetData($tRI_KD, 'hDevice') ConsoleWrite($hDevice & @LF) ConsoleWrite(DllStructGetData($tRI_KD, 'VKey') & @LF) ConsoleWrite(DllStructGetData($tRI_KD, 'hDevice') & @LF) _GetRawInputDeviceInfo($hDevice, $RIDI_DEVICEINFO, $pRIDI_HID, $iRIDI_HID) If $hDevice = 0x00A501BB Then $USB = 1 EndIf EndIf $tRI_KD = 0 Return 'GUI_RUNDEFMSG' EndFunc Func _EXIT() GUIDelete() Exit EndFuncRawInput.au3 Link to comment Share on other sites More sharing options...
Authenticity Posted July 31, 2009 Share Posted July 31, 2009 Hmm, confused. Can you explain it a bit more? The WM_INPUT message should give your application enough information regarding the event and the state of the device. If you need to inform a window or a function to process this input without waiting to luckily hit the pull time of a global variable, if that is the case, either via a send message or a function call. Correct me where I'm wrong. Link to comment Share on other sites More sharing options...
boogieoompa Posted July 31, 2009 Author Share Posted July 31, 2009 I think my issue is considerably easier than most of the other posts regarding this topic. $WM_Input only seems to give me the size of the stream I do not know how to parse out the indivudal keystroke. The 2nd issue is chaning this input, the code I recieved so far seems to monitor the signal I do not know how to hold the input in my app before it reaches say notepad. Effectivly from a simplistic perspective I am trying to have this HID that sends say a "J" to notepad instead send a "K". Currently the code I have does that but it does so in a very inefficient manner and I am sure by using the rawinput there is a way of fixing this but I cant seem to figure out how. Link to comment Share on other sites More sharing options...
Authenticity Posted August 1, 2009 Share Posted August 1, 2009 You can do something like this, the hook procedure is called prior to the WM_INPUT handler in this case because you've register it with UsagePage and Usage of a generic keyboard. expandcollapse popup#include <GUIConstantsEx.au3> #include <RawInput.au3> #include <WinAPI.au3> HotKeySet('{ESC}', '_EXIT') Global Const $RIM_USER = 0xE0 Global $tRID_KD, $pRID_KD, $iRID_KD Global $tRIH, $iRIH Global $iNumDevices Global $hGUI Global $hHook, $hFunc, $pFunc $hGUI = GUICreate('Test', 100, 100) $hFunc = DllCallbackRegister('_KeyboardHookProc', 'lresult', 'int;wparam;lparam') $pFunc = DllCallbackGetPtr($hFunc) $hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, $pFunc, _WinAPI_GetModuleHandle(0)) GUIRegisterMsg($WM_INPUT, 'OnInput') $tRID_KD = DllStructCreate($tagRAWINPUTDEVICE) $pRID_KD = DllStructGetPtr($tRID_KD) $iRID_KD = DllStructGetSize($tRID_KD) $tRIH = DllStructCreate($tagRAWINPUTHEADER) $iRIH = DllStructGetSize($tRIH) $iNumDevices = 1 DllStructSetData($tRID_KD, 'usUsagePage', 0x01) DllStructSetData($tRID_KD, 'usUsage', 0x06) DllStructSetData($tRID_KD, 'dwFlags', BitOR($RIDEV_NOLEGACY, $RIDEV_INPUTSINK)) DllStructSetData($tRID_KD, 'hwndTarget', $hGUI) _RegisterRawInputDevices($pRID_KD, $iNumDevices, $iRID_KD) While 1 Sleep(20) WEnd Func OnInput($hwnd, $iMsg, $iwParam, $ilParam) Local $tRI_KD, $pRI_KD, $iRI_KB Local $iSize Switch BitAND($iwParam, 0xFF) Case $RIM_INPUT, $RIM_INPUTSINK $tRI_KD = DllStructCreate($tagRAWINPUT_KEYBOARD) $pRI_KD = DllStructGetPtr($tRI_KD) $iRI_KB = DllStructGetSize($tRI_KD) _GetRawInputData($ilParam, $RID_INPUT, $pRI_KD, $iRI_KB, $iRIH) If Not @error Then ConsoleWrite('-WM_INPUT: hDevice => ' & DllStructGetData($tRI_KD, 'hDevice') & _ ', Msg => ' & DllStructGetData($tRI_KD, 'Message') & _ ', VKey => ' & DllStructGetData($tRI_KD, 'VKey') & @CRLF) EndIf Case $RIM_USER $tRI_KD = DllStructCreate($tagRAWINPUT_KEYBOARD, $ilParam) If DllStructGetData($tRI_KD, 'VKey') <> 27 Then ; Escape. ConsoleWrite('-WM_INPUT: hDevice => ' & DllStructGetData($tRI_KD, 'hDevice') & _ ', Msg => ' & DllStructGetData($tRI_KD, 'Message') & _ ', VKey => ' & DllStructGetData($tRI_KD, 'VKey') & @CRLF) Return True EndIf Return False EndSwitch Return $GUI_RUNDEFMSG EndFunc Func _KeyboardHookProc($iCode, $iwParam, $ilParam) Local $tRI_KD, $pRI_KD Local $tKBDLLHS Local $iMsg, $iVkCode If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) $tKBDLLHS = DllStructCreate($tagKBDLLHOOKSTRUCT, $ilParam) $iMsg = $iwParam $iVkCode = DllStructGetData($tKBDLLHS, 'vkCode') $tRI_KD = DllStructCreate($tagRAWINPUT_KEYBOARD) $pRI_KD = DllStructGetPtr($tRI_KD) DllStructSetData($tRI_KD, 'hDevice', 0x12345678) DllStructSetData($tRI_KD, 'VKey', $iVkCode) DllStructSetData($tRI_KD, 'Message', $iMsg) If OnInput($hGUI, $WM_INPUT, $RIM_USER, $pRI_KD) Then Return 1 ConsoleWrite('-_KeyboardHookProc: Message => ' & $iwParam & _ ', VKey => ' & $iVkCode & @CRLF) Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) EndFunc Func _EXIT() GUIDelete() _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hFunc) Exit EndFunc Replace the hDevice to you device value and play around with the devices events to achieve a unique way to tell one device to do something differently on a system level. Link to comment Share on other sites More sharing options...
boogieoompa Posted August 3, 2009 Author Share Posted August 3, 2009 Thanks I will try that and let you know how it goes. Might take me a day or two to figure it out however, thanks. Link to comment Share on other sites More sharing options...
boogieoompa Posted August 3, 2009 Author Share Posted August 3, 2009 Its weird I keep getting errors in the RawInput file on line 583 and 516 saying "Subscript used with non-Array variable." I dont wnat to change the file because I assume it was scripted correctly. Have you heard/seen that before? Link to comment Share on other sites More sharing options...
Authenticity Posted August 3, 2009 Share Posted August 3, 2009 Are you using the last updated script? Also, if you get this error I can only assume that the last parameter is not 'user32.dll' or that it's not a valid handle to user32.dll required by these function. Anyway, I need to update the library to return @error and @extended instead. Link to comment Share on other sites More sharing options...
boogieoompa Posted August 4, 2009 Author Share Posted August 4, 2009 I downloaded the rawinput from the thread uploaded on May 24th. Didnt find one more recent than that. The script seems to be choking whenever $aRet is defined. $hDll is defined as user32.dll but it is not writing to $aRet as an array. $aRet = DllCall($hDll, 'uint', 'GetRawInputData', 'hwnd', $hRawInput, 'uint', $iCommand, 'ptr', $pData, 'uint*', $iSize, 'uint', $iSizeHeader) Link to comment Share on other sites More sharing options...
Authenticity Posted August 4, 2009 Share Posted August 4, 2009 Hi, can you post the relevant code that calls this function? No check is done within the function for parameters correctness so it's hard to point out the faulting parameter(s). Link to comment Share on other sites More sharing options...
boogieoompa Posted August 4, 2009 Author Share Posted August 4, 2009 WOW so many calls and references lol. So I figured out a little about the hook calls but I'm not sure how to set an I/O. I also identefied all of the identifiers of the USB device however I cannot make the hook proceedures work. I read the winapi documentation and couldnt figure it out. I played with numerous variables and I end up with several issues primarily around the input output variable. How do you write a hook command that simply states if you recieve "a" from device 0x0190016B than convert it to "b". Thanks for all your help so far. Which I was more familar with this though I will say I've leared quite alot, I had no idea it would take so much effort. expandcollapse popup#include <GUIConstantsEx.au3> #include <RawInput.au3> #include <WinAPI.au3> HotKeySet('{ESC}', '_EXIT') Global Const $RIM_USER = 0xE0 Global $tRID_KD, $pRID_KD, $iRID_KD Global $tRIH, $iRIH Global $iNumDevices Global $hGUI Global $hHook, $hFunc, $pFunc $hGUI = GUICreate('Test', 100, 100) $hFunc = DllCallbackRegister('_KeyboardHookProc', 'lresult', 'int;wparam;lparam') $pFunc = DllCallbackGetPtr($hFunc) $hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, $pFunc, _WinAPI_GetModuleHandle(0)) GUIRegisterMsg($WM_INPUT, 'OnInput') $tRID_KD = DllStructCreate($tagRAWINPUTDEVICE) $pRID_KD = DllStructGetPtr($tRID_KD) $iRID_KD = DllStructGetSize($tRID_KD) $tRIH = DllStructCreate($tagRAWINPUTHEADER) $iRIH = DllStructGetSize($tRIH) $iNumDevices = 1 DllStructSetData($tRID_KD, 'usUsagePage', 0x01) DllStructSetData($tRID_KD, 'usUsage', 0x06) DllStructSetData($tRID_KD, 'dwFlags', BitOR($RIDEV_NOLEGACY, $RIDEV_INPUTSINK)) DllStructSetData($tRID_KD, 'hwndTarget', $hGUI) _RegisterRawInputDevices($pRID_KD, $iNumDevices, $iRID_KD) While 1 Sleep(20) WEnd Func OnInput($hwnd, $iMsg, $iwParam, $ilParam) Local $tRI_KD, $pRI_KD, $iRI_KB Local $iSize Switch BitAND($iwParam, 0xFF) Case $RIM_INPUT, $RIM_INPUTSINK $tRI_KD = DllStructCreate($tagRAWINPUT_KEYBOARD) $pRI_KD = DllStructGetPtr($tRI_KD) $iRI_KB = DllStructGetSize($tRI_KD) _GetRawInputData($ilParam, $RID_INPUT, $pRI_KD, $iRI_KB, $iRIH) If Not @error Then ConsoleWrite('-WM_INPUT: hDevice => ' & DllStructGetData($tRI_KD, 'hDevice') & _ ', Msg => ' & DllStructGetData($tRI_KD, 'Message') & _ ', VKey => ' & DllStructGetData($tRI_KD, 'VKey') & @CRLF) EndIf Case $RIM_USER $tRI_KD = DllStructCreate($tagRAWINPUT_KEYBOARD, $ilParam) If DllStructGetData($tRI_KD, 'VKey') <> 27 Then ; Escape. ConsoleWrite('-WM_INPUT: hDevice => ' & DllStructGetData($tRI_KD, 'hDevice') & _ ', Msg => ' & DllStructGetData($tRI_KD, 'Message') & _ ', VKey => ' & DllStructGetData($tRI_KD, 'VKey') & @CRLF) Return True EndIf Return False EndSwitch Return $GUI_RUNDEFMSG EndFunc Func _KeyboardHookProc($iCode, $iwParam, $ilParam) Local $tRI_KD, $pRI_KD Local $tKBDLLHS Local $iMsg, $iVkCode If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) $tKBDLLHS = DllStructCreate($tagKBDLLHOOKSTRUCT, $ilParam) $iMsg = $iwParam $iVkCode = DllStructGetData($tKBDLLHS, 'vkCode') $tRI_KD = DllStructCreate($tagRAWINPUT_KEYBOARD) $pRI_KD = DllStructGetPtr($tRI_KD) DllStructSetData($tRI_KD, 'hDevice', 0x0190016B) DllStructSetData($tRI_KD, 'VKey', $iVkCode) DllStructSetData($tRI_KD, 'Message', $iMsg) If OnInput($hGUI, $WM_INPUT, $RIM_USER, $pRI_KD) Then Return 1 ConsoleWrite('-_KeyboardHookProc: Message => ' & $iwParam & _ ', VKey => ' & $iVkCode & @CRLF) Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) EndFunc Func _EXIT() GUIDelete() _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hFunc) Exit EndFunc Link to comment Share on other sites More sharing options...
Authenticity Posted August 4, 2009 Share Posted August 4, 2009 Heh, honestly, I see no use for this library in this case as the hook will always be notified about the event earlier than the handler. I can only suggest to use a lock hot-key that will instruct the keyboard hook to assume A state what a variable is true and B state when a variable is false, like assuming A state input to be from the generic keyboard while handling the B state of the HID in a different mode. If you find a way please post it in the HID topic, thanks >_<. Link to comment Share on other sites More sharing options...
boogieoompa Posted August 5, 2009 Author Share Posted August 5, 2009 (edited) Yeah that was my originial idea but it seemed to have a weird sporatic behavior. The code I posted at the begining of this post took a hotkey that went thru logic to see where the input was comming from however this was fairly inconsistant since many times I had to press the button 2-3 times for it to register. I figured a hook proceedure would be a bit more responsive. Thanks :-) Edited August 5, 2009 by boogieoompa Link to comment Share on other sites More sharing options...
boogieoompa Posted August 6, 2009 Author Share Posted August 6, 2009 OK so this seemed to kind of work. For those who did not read the last thread my goal was to capture input from an HID device and remap it. In this case remaping "a" to "j" whenever the computer recieves an "a" from the HID. The problem at the moment is it is not accepting a from the keyboard since the send command is traping it again. Is there a more elequant way of performing this task or is there a way around the send loop? Thanks expandcollapse popup#include <RawInput.au3> HotKeySet('{ESC}', '_EXIT') HotKeySet("a", "FuncTrap") Global $tRID_KD, $pRID_KD, $iRID_KD Global $tRIH, $pRIH, $iRIH Global $iNumDevices Global $hGUI , $pData $hGUI = GUICreate('Test', 100, 100) GUIRegisterMsg($WM_INPUT, 'OnInput') $tRID_KD = DllStructCreate($tagRAWINPUTDEVICE) $pRID_KD = DllStructGetPtr($tRID_KD) $iRID_KD = DllStructGetSize($tRID_KD) $tRIH = DllStructCreate($tagRAWINPUTHEADER) $pRIH = DllStructGetPtr($tRIH) $iRIH = DllStructGetSize($tRIH) $iNumDevices = 1 DllStructSetData($tRID_KD, 'usUsagePage', 0x01) DllStructSetData($tRID_KD, 'usUsage', 0x06) DllStructSetData($tRID_KD, 'dwFlags', BitOR($RIDEV_NOLEGACY, $RIDEV_INPUTSINK)) DllStructSetData($tRID_KD, 'hwndTarget', $hGUI) _RegisterRawInputDevices($pRID_KD, $iNumDevices, $iRID_KD) While 1 Sleep(20) WEnd Func FuncTrap() EndFunc Func FuncSend() send("j") EndFunc Func FuncSend2() send("a") EndFunc Func OnInput($hwnd, $iMsg, $iwParam, $ilParam) Local $tRI_KD, $pRI_KD, $iRI_KB Local $tRIDI_HID, $pRIDI_HID, $iRIDI_HID Local $hDevice $tRI_KD = DllStructCreate($tagRAWINPUT_KEYBOARD) $pRI_KD = DllStructGetPtr($tRI_KD) $iRI_KB = DllStructGetSize($tRI_KD) $tRIDI_HID = DllStructCreate($tagRIDDEVICEINFO_HID) $pRIDI_HID = DllStructGetPtr($tRIDI_HID) $iRIDI_HID = DllStructGetSize($tRIDI_HID) DllStructSetData($tRIDI_HID, 'cbSize', $iRIDI_HID) _GetRawInputData($ilParam, $RID_INPUT, $pRI_KD, $iRI_KB, $iRIH) If Not @error Then $hDevice = DllStructGetData($tRI_KD, 'hDevice') ConsoleWrite($hDevice & @LF) ConsoleWrite(DllStructGetData($tRI_KD, 'VKey') & @LF) ConsoleWrite(DllStructGetData($tRI_KD, 'hDevice') & @LF) _GetRawInputDeviceInfo($hDevice, $RIDI_DEVICEINFO, $pRIDI_HID, $iRIDI_HID) If $hDevice = 0x0190016B Then ; ClipPut ($hDevice&","& $RIDI_DEVICEINFO&","& $pRIDI_HID&","& $iRIDI_HID) FuncSend() ; Msgbox(0,"Hoorah", DllStructGetData($tRI_KD, 'hDevice') ) Else FuncSend2() EndIf EndIf $tRI_KD = 0 Return 'GUI_RUNDEFMSG' EndFunc Func _EXIT() GUIDelete() Exit EndFunc Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now