Bilgus Posted April 25, 2018 Posted April 25, 2018 (edited) Recently a user asked given two keyboards how to determine which keyboard was pressed this is the start of such functionality I was already given permission to post this example by a moderator before I bothered expandcollapse popup;Bilgus 2018 ;Determine which keyboard was pressed #include <Array.au3> #include <WinAPISys.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global Const $HWND_MESSAGE = (-3) ;create a message-only window when set as Parent ;RAWINPUTDEVICE Constants Global Const $HID_USAGE_PAGE_GENERIC = 0x1 Global Const $HID_USAGE_GENERIC_KEYBOARD = 0x6 Global $ghSelectedDevice Global $gaKeyboards = EnumRawKeyboards("\HID") If IsArray($gaKeyboards) And $gaKeyboards[0][0] >= 1 Then $ghSelectedDevice = $gaKeyboards[1][0] ; hard coded change to suit _ArrayDisplay($gaKeyboards, '_WinAPI_EnumRawInputDevices', "", 0, Default, "Handle|Type|VID|Keys") ;Not Needed... Global $hTarget = GUICreate("main", 10, 10, Default, Default, Default, Default, $HWND_MESSAGE) ;Dummy window to recieve messages Register_RawInput($HID_USAGE_PAGE_GENERIC, $HID_USAGE_GENERIC_KEYBOARD, $RIDEV_INPUTSINK, $hTarget) ;$RIDEV_INPUTSINK recieves input when not foreground ; Register WM_INPUT message GUIRegisterMsg($WM_INPUT, 'WM_INPUT') HotKeySet("{ESC}", _Exit) While 1 Sleep(1000) WEnd Func Device_Pressed() ConsoleWrite("Device Pressed" & @CRLF) EndFunc ;==>Device_Pressed Func _Exit() Exit EndFunc ;==>_Exit Func Register_RawInput($iUsagePage, $iUsage, $iFlags, $hTargetHwnd) Local $tRID = DllStructCreate($tagRAWINPUTDEVICE) DllStructSetData($tRID, 'UsagePage', $iUsagePage) DllStructSetData($tRID, 'Usage', $iUsage) DllStructSetData($tRID, 'Flags', $iFlags) DllStructSetData($tRID, 'hTarget', $hTargetHwnd) ; Register HID input to obtain info from devices _WinAPI_RegisterRawInputDevices($tRID) EndFunc ;==>Register_RawInput Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam) ;Callback from RawInput #forceref $iMsg, $wParam ;'struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct' Local $tRIH = DllStructCreate($tagRAWINPUTHEADER) If _WinAPI_GetRawInputData($lParam, $tRIH, DllStructGetSize($tRIH), $RID_HEADER) And DllStructGetData($tRIH, "Type") = $RIM_TYPEKEYBOARD Then ConsoleWrite("0x" & Hex(DllStructGetData($tRIH, "hDevice")) & @CRLF) If $ghSelectedDevice = DllStructGetData($tRIH, "hDevice") Then Device_Pressed() Else ;Different Device ConsoleWrite("Different Device Pressed" & @CRLF) EndIf EndIf Return $GUI_RUNDEFMSG ;Pass on to default winproc EndFunc ;==>WM_INPUT Func EnumRawKeyboards($sDeviceNameMatch = "") ;Returns array of keyboard device IDs Local $tInfo, $aData = _WinAPI_EnumRawInputDevices() If IsArray($aData) Then Local $aKeyboards[$aData[0][0] + 1][4] ;'dword Size;dword Type;';'struct;dword KbType;dword KbSubType;dword KeyboardMode;dword NumberOfFunctionKeys;dword NumberOfIndicators;dword NumberOfKeysTotal;endstruc' Local $_tagRID_INFO_KEYBOARD = $tagRID_INFO_KEYBOARD If StringRight($_tagRID_INFO_KEYBOARD, 1) <> "t" Then $_tagRID_INFO_KEYBOARD &= "t" ; t is missing from endstruct Local $iCt = 0, $iSz Local $tInfo, $tDeviceName, $sDeviceName For $i = 1 To $aData[0][0] $tInfo = DllStructCreate($_tagRID_INFO_KEYBOARD) If _WinAPI_GetRawInputDeviceInfo($aData[$i][0], $tInfo, DllStructGetSize($tInfo), $RIDI_DEVICEINFO) And $aData[$i][1] = $RIM_TYPEKEYBOARD Then $iSz = _WinAPI_GetRawInputDeviceInfo($aData[$i][0], 0, 0, $RIDI_DEVICENAME) ;Get bytes needed $tDeviceName = DllStructCreate('wchar[' & $iSz + 1 & ']') ;Holds device name string If _WinAPI_GetRawInputDeviceInfo($aData[$i][0], $tDeviceName, DllStructGetSize($tDeviceName), $RIDI_DEVICENAME) Then $sDeviceName = DllStructGetData($tDeviceName, 1) If $sDeviceNameMatch <> "" And Not StringInStr($sDeviceName, $sDeviceNameMatch) Then ContinueLoop $iCt += 1 $aKeyboards[$iCt][0] = $aData[$i][0] ;Handle $aKeyboards[$iCt][1] = $aData[$i][1] ;Type $aKeyboards[$iCt][2] = $sDeviceName $aKeyboards[$iCt][3] = DllStructGetData($tInfo, "NumberOfKeysTotal") EndIf EndIf Next $aKeyboards[0][0] = $iCt ; Write count of keyboard devices to array ReDim $aKeyboards[$iCt + 1][4] ;Resize array EndIf Return $aKeyboards EndFunc ;==>EnumRawKeyboards Edited April 27, 2018 by Bilgus Cleaned Up Code Added Filter to Enum Earthshine, EskoFIN, Gianni and 1 other 4
martinandersen3d Posted January 7, 2019 Posted January 7, 2019 (edited) How do I get the key that is pressed? :-) I would love to call a method like: Funk keyboardAndCharacter($keyboardId. $keyPressedId) Edited January 7, 2019 by martinandersen3d
Moderators Melba23 Posted January 8, 2019 Moderators Posted January 8, 2019 martinandersen3d, To do that would run into the forum prohibition on keyloggers as explained here: So please do not pursue this any further. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Deye Posted January 10, 2019 Posted January 10, 2019 (edited) Just a thought, Now all is left is to think of a way of securing the keyboard to the users foreground window process with a blockinput applied on to other processes Also that ALT cannot be sent without the user actually sending it from the keyboard device Maybe some idea as described here can come into play As in quick to post: haven't tried anything yet .. Edit : just saw BlockInputEx.au3 .. Deye Edited January 10, 2019 by Deye
AXLE Posted January 11, 2019 Posted January 11, 2019 On 1/9/2019 at 5:24 AM, Melba23 said: martinandersen3d, To do that would run into the forum prohibition on keyloggers as explained here: So please do not pursue this any further. M23 I just noticed this and just need to confirm the definition of "Keylogger" here. I have future plans for an app that allows Two users at one desktop, so Two keyboards and Two mice. It also incorporates the concept of an additional custom keyboard in a "Gaming" environment. This is not a new concept, but would something like that step over the boundaries here. I am guessing apps for testing scan-codes for damaged keys may be iffy as well? AXLE "Writing code to carry out an intended set of tasks is relatively easy. Writing code to carry out ONLY an intended set of tasks, well that can be a little more challenging." Alex Maddern
Moderators JLogan3o13 Posted January 11, 2019 Moderators Posted January 11, 2019 @AXLE did you read the post to which Melba pointed you? It is pretty straight-forward; if you are checking for more than a handful of keys, it is not something we will support. "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum!
AXLE Posted January 12, 2019 Posted January 12, 2019 JLogan3o13, Yes I read all. The fact that checking for keypress, keyboard scancodes, and user input from the keyboard in general is a necessary part of programming makes this a somewhat grey area. Trying to differentiate between what is 'Getting User keyboard Input' and a Keylogger is somewhat grey and easy to overstep under the definition of 'checking for a more than a few keys'. If this refers to 'Any or all keyboard Input', that's OK, I will be careful to not accidentally post code that may be viewed that way. If this is referring to Low Level capture from the windows message stream, then that's slightly different, but still requires some care on my behalf. So I am just asking to ensure that I don't accidentally post code that may be viewed that way I you have or know of more information on this subject I will find that helpful. AXLE "Writing code to carry out an intended set of tasks is relatively easy. Writing code to carry out ONLY an intended set of tasks, well that can be a little more challenging." Alex Maddern
AXLE Posted January 12, 2019 Posted January 12, 2019 43 minutes ago, AXLE said: I you have or know of more information on this subject I will find that helpful. The above question still applies. After searching for banned posts I am starting to gauge a little better.. Links to more examples of locked/banned will be helpful.. It's sad that AutoIt gets a bad rap for what is more easily achievable in other more mainstream languages. "Writing code to carry out an intended set of tasks is relatively easy. Writing code to carry out ONLY an intended set of tasks, well that can be a little more challenging." Alex Maddern
kaz Posted July 27, 2019 Posted July 27, 2019 (edited) If i have two keyboards, how to block key from one, to remap key to do some script, or others operations. The other keyboard must work as usual. The script could be for example, open a program, connect to a database, execute select command, execute some key sequence. With the code above, we can fin wich device and wich key is pressed but i didn't find how to block a device. It's possible to find a key pressed and block some keys with a keyboard hook, but i didn't find how to determine the device. If we use Wm_INPUT and keyboard hook, hook arrive before wm_input. If wm_input arrive first, we could put a variable to block in the hook, but it's not. Any help please. Edited July 28, 2019 by kaz
Bilgus Posted July 31, 2019 Author Posted July 31, 2019 (edited) Quote It's Complicated. Edited July 31, 2019 by Bilgus
kaz Posted July 31, 2019 Posted July 31, 2019 (edited) i've search a lot after my last post, spend some time, sleep less and i finally found some code. I did a small dll and it work pretty well. i'll try to do without , only with autoit. EDIT : After some tests, i think it's not possible without using a dll We must create a hook with $WH_KEYBOARD but it seem not working, only $WH_KEYBOARD_LL can be use with autoit. If someone else can confirme. EDIT 2 : After plying a litle, it seem send function doesn't send raw information of any keyboard, so hDevice is empty. Edited August 3, 2019 by kaz
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