[SOLVED]WM_INPUT never arrived [Win10 b4bit + Lazarus1.8.4 + FPC3.0.4] lazarus / 34-Windows ---------------------------------------------------------------------- kinlion · 2018-10-17 06:52 Hi all, I'm trying to use windows raw input to get a IC card reader input, the IC card reader is kown by windows as a HID keyboard. as described in the post:https://forum.lazarus.freepascal.org/index.ph p/topic,34797.msg228966.html#msg228966 Firstly, I overide form.InitializeWnd, in which to register the raw device. Then I add the WM_INPUT message handler to my form, but the handler never executed. At last I override the WndProc of my form,but still no WM_INPUT comes. Can anyone tell me how to do? Thanks in advance. Bellow is some of my code: ---------------------------- procedure registerHIDDevice(targetHandle: HWND); var   Rid: array[0..0] of RAWINPUTDEVICE; begin   with Rid[0] do   begin     usUsagePage := $01;     usUsage := $06;     dwFlags := RIDEV_NOLEGACY or RIDEV_INPUTSINK;   // adds HID keyboard and also ignores legacy keyboard messages     hwndTarget := targetHandle;   end;   if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) = FALSE) then     raise Exception.Create('Failed to register'); end; procedure TfmMain.InitializeWnd; override; begin   inherited InitializeWnd;   registerHIDDevice(Self.Handle); end; procedure TfmMain.getHIDInput(var msg: TMessage); { https://docs.microsoft.com/zh-cn/windows/desktop/inputdev/using-raw- input } var   dwSize: UINT;   lpb: LPBYTE;   raw: PRAWINPUT; begin   GetRawInputData(HRAWINPUT(msg.lParam), RID_INPUT, nil, @dwSize,                   sizeof(RAWINPUTHEADER));   GetMem(lpb, dwSize);   if (lpb = nil) then Exit;   if (GetRawInputData(HRAWINPUT(msg.lParam), RID_INPUT, lpb, @dwSize,       sizeof(RAWINPUTHEADER)) <> dwSize ) then   begin     ShowMessage('Bad data size');     Freemem(lpb);     Exit;   end;   raw := PRAWINPUT(lpb);   if (raw^.header.dwType = RIM_TYPEKEYBOARD) then   begin     ShowMessage(Format('Kbd:'                 + '\n\tmake=%04x'                 + '\n\tFlags:%04x'                 + '\n\tReserved:%04x'                 + '\n\tExtraInformation:%08x'                 + '\n\tmsg=%04x'                 + '\n\tVK=%04x',               [                 raw^.data.keyboard.MakeCode,                 raw^.data.keyboard.Flags,                 raw^.data.keyboard.Reserved,                 raw^.Data.keyboard.ExtraInformation,                 raw^.data.keyboard.Message,                 raw^.data.keyboard.VKey               ])               );   end;   DefRawInputProc(@lpb, 1, sizeof(RAWINPUTHEADER));   Freemem(lpb); end; procedure TfmMain.WndProc(var TheMessage: TLMessage); override; begin   if TheMessage.msg = WM_INPUT then     getHIDInput(TheMessage);   inherited WndProc(TheMessage); end; ---------------------------------------------------------------------- kinlion · 2018-10-17 06:59 I'm sure the card reader is OK because when I remove RIDEV_NOLEGACY  flag from dwFlags during register raw input device,  card id can be read in to a text edit. ---------------------------------------------------------------------- marcov · 2018-10-17 07:57 I'm no expert on the matter, but did you read through this: http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non- user_messages_in_your_window ? ---------------------------------------------------------------------- kinlion · 2018-10-17 08:32 YES, IT WORKS THANK YOU MARCOV! But, I found the traditional PS/2 keyboard also gernates WM_INPUT message. I can't distinguish the messages from card reader and PS/2 keyboard. However, it's anothor problem. Quote from: marcov on October 17, 2018, 09:57:15 amI'm no expert on the matter, but did you read through this: http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non- user_messages_in_your_window ? ---------------------------------------------------------------------- Remy Lebeau · 2018-10-22 21:54 Quote from: marcov on October 17, 2018, 09:57:15 amI'm no expert on the matter, but did you read through this: http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non- user_messages_in_your_window ? Note that SetWindowSubclass() is preferred over SendWindowLong/Ptr().  See Subclassing Controls and Safer subclassing on MSDN. Quote from: kinlion on October 17, 2018, 10:32:22 amBut, I found the traditional PS/2 keyboard also gernates WM_INPUT message. In fact, ANY type of input device can, whether it is PS/2, USB, etc. Quote from: kinlion on October 17, 2018, 10:32:22 amI can't distinguish the messages from card reader and PS/2 keyboard. Yes, you can.  One of the defining features of the Raw Input API is the ability to distinguish between specific devices.  The WM_INPUT message gives you a handle to the specific device that is generating the message.  You can use GetRawInputDeviceInfo() if you need to retrieve specific details about that device.  On the other hand, you are not going to get WM_INPUT messages from devices that you have not registered with RegisterRawInputDevices().  So, if you register only the card reader, then you will get messages only from the card reader and not the PS/2 keyboard. ---------------------------------------------------------------------- kinlion · 2018-12-08 07:09 Quote from: Remy Lebeau on October 22, 2018, 11:54:56 pmYes, you can.  One of the defining features of the Raw Input API is the ability to distinguish between specific devices.  The WM_INPUT message gives you a handle to the specific device that is generating the message.  You can use GetRawInputDeviceInfo() if you need to retrieve specific details about that device.  On the other hand, you are not going to get WM_INPUT messages from devices that you have not registered with RegisterRawInputDevices().  So, if you register only the card reader, then you will get messages only from the card reader and not the PS/2 keyboard. Yes, finally I can filter the messages by checking device info. But I still don't know how to register ONLY the card-reader. The problem is: The card-reader makes itself as a HID keyboard. To register raw input device, one must specify usUsagePage and/or usUsage of the record RAWINPUTDEVICE, and meanwhile the card-reader and PS/2 keyboard share the same values. So, how can I register only the card-reader?  That would be great if can. ---------------------------------------------------------------------- Remy Lebeau · 2018-12-10 20:12 Quote from: kinlion on December 08, 2018, 08:09:06 amBut I still don't know how to register ONLY the card-reader. The problem is: The card-reader makes itself as a HID keyboard. To register raw input device, one must specify usUsagePage and/or usUsage of the record RAWINPUTDEVICE, and meanwhile the card-reader and PS/2 keyboard share the same values. Which values exactly? ---------------------------------------------------------------------- kinlion · 2018-12-13 06:07 Quote from: Remy Lebeau on December 10, 2018, 09:12:07 pmWhich values exactly? When register raw input device, I used: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     usUsagePage := $01;    usUsage := $06;  And the start of the file name of my card-reader is: '\\?\HID#VID_FFFF&PID_0035&MI_00#' ---------------------------------------------------------------------- Remy Lebeau · 2018-12-13 19:33 Quote from: kinlion on December 13, 2018, 07:07:26 amWhen register raw input device, I used: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     usUsagePage := $01;    usUsage := $06;  OK, that pair is generic for keyboards, so it will register all available keyboards.  In which case, to handle messages only from the card reader, you will have to use GetRawInputDeviceList() and GetRawInputDeviceInfo() to discover the HANDLE of the card reader specifically, and then you can ignore any WM_INPUT messages that do not carry that same HANDLE in their RAWINPUT.header info.  No need to call GetRawInputDeviceInfo() on every message. Otherwise, contact the card reader manufacturer and see if there is an alternative UsagePage+Usage pair available for their card reader that does not identify it as a keyboard. ---------------------------------------------------------------------- kinlion · 2018-12-14 09:34 Quote from: Remy Lebeau on December 13, 2018, 08:33:29 pmOtherwise, contact the card reader manufacturer and see if there is an alternative UsagePage+Usage pair available for their card reader that does not identify it as a keyboard. I hope there is.