Recent

Author Topic: no wm_input message until other messages are being sent  (Read 5857 times)

dmudie

  • New member
  • *
  • Posts: 9
no wm_input message until other messages are being sent
« on: November 14, 2016, 06:05:59 pm »
I have progressed with reading the USB Key Pedal system. 

I have registered the raw device, and have set up a message loop that handles wm_input.  I am able to read the raw data and determine which pedals are pressed and which ones are released. 

All good, and thanks for the help getting to this point. 

The problem I am having now is that the wm_input message is not being processed by my message loop until other messages (events) are being received. 

For instance, I can click on one of the foot pedals, and the wm_input message is not sent/received until I do something else on the window such as drag the window across.  A simple work around is to set up a timer and have it enabled.  I don't even have to do anything with the event.  Just having the event triggered causes the wm_import messages to be received.

Any insights on what is going on / how to properly handle this would be appreciated.  I'm sure my workaround is not the best way of dealing with it.

Thanks,

David




Code: Pascal  [Select][+][-]
  1. unit umain;
  2.  
  3. {$mode OBJFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   ExtCtrls, jwawinuser, windows;
  10.  
  11. const
  12.   BUFFER_LENGTH =              255;
  13.  
  14.  
  15. type
  16.  
  17.   { TForm1 }
  18.  
  19.   TForm1 = class(TForm)
  20.     bRegisterDevice: TButton;
  21.     cbLeft: TCheckBox;
  22.     cbMiddle: TCheckBox;
  23.     cbRight: TCheckBox;
  24.     Memo1: TMemo;
  25.     Panel1: TPanel;
  26.     Timer1: TTimer;
  27.  
  28.     procedure bRegisterDeviceClick(Sender: TObject);
  29.     procedure FormCreate(Sender: TObject);
  30.     procedure Timer1Timer(Sender: TObject);
  31.   private
  32.     { private declarations }
  33.  
  34.   public
  35.     { public declarations }
  36.     function WMInput(wParam: WParam; lParam: LParam):LRESULT;
  37.   end;
  38.  
  39. var
  40.   Form1: TForm1;
  41.  
  42. implementation
  43.  
  44. {$R *.lfm}
  45.  
  46.  
  47. var
  48.   PrevWndProc:windows.WNDPROC;
  49.  
  50.  
  51.  
  52.   function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam;
  53.   lParam: LParam): LRESULT; stdcall;
  54.   // replace the message loop in order to handle the WM_INPUT message
  55. begin
  56.   case uMsg of
  57.   WM_INPUT:
  58.     begin
  59. //      Form1.Memo1.Lines.Add('Beep');
  60.  
  61.       result := Form1.WMInput(wParam,lParam);
  62.  //     result := DefWindowProc(Ahwnd,uMsg,wParam,LParam);
  63.      end;
  64.   end;
  65.  
  66.   // if the message is not a WM_INPUT, then call the default message loop to handle it
  67.   Result := CallWindowProc(PrevWndProc, Ahwnd, uMsg, WParam, LParam);
  68. end;
  69.  
  70.  
  71. { TForm1 }
  72.  
  73.  
  74. function TForm1.WMInput(wParam: WParam; lParam: LParam):LRESULT;
  75. var
  76. //  pBuffer     : ^RAWINPUT;
  77.   pBuffer     : ^char;
  78.   lwBufferLength: LongWord;
  79.   iBytesCopied: integer;
  80.  
  81.   cButtonStatus: char;
  82.  
  83. begin
  84.   Result := 0;
  85.   Memo1.Lines.Add('WM_INPUT');
  86.   Memo1.Lines.Add('LParam : ' + IntToStr(LParam));
  87.   Memo1.Lines.Add('WParam : ' + IntToStr(WParam));
  88.  
  89.   lwBufferLength := SizeOf(RAWINPUTHEADER);
  90.  
  91. //  if GetRawInputData(hToRawInput,RID_INPUT,pBuffer,lwBufferLength,0) <> 0 then
  92.   if GetRawInputData(HRAWINPUT(lParam),RID_INPUT,NIL,lwBufferLength,SizeOf(RAWINPUTHEADER)) <> 0 then
  93.      begin
  94.        Memo1.Lines.Add('Error Getting Buffer Size GetRawInputData(hToRawInput,RID_HEADER,pBuffer,lwBufferLength,0)');
  95.        exit;
  96.      end;
  97.  
  98.  
  99.   Memo1.Lines.Add('Header Buffer Size is ' + IntToStr(lwBufferLength));
  100.  
  101.   GetMem(pBuffer,lwBufferLength);
  102.  
  103.   try
  104.  
  105.      iBytesCopied := GetRawInputData(HRAWINPUT(lParam),RID_INPUT,pBuffer,lwBufferLength,SizeOf(RAWINPUTHEADER));
  106.      Memo1.Lines.Add('Bytes Copied : ' + IntToStr(iBytesCopied));
  107.  
  108.      if  iBytesCopied < 1 then
  109.      begin
  110.        Memo1.Lines.Add('Error Getting Header GetRawInputData(hToRawInput,RID_HEADER,pBuffer,lwBufferLength,0)');
  111.        exit;
  112.      end;
  113.  
  114.  
  115.   cButtonStatus := (pBuffer+25)^;
  116.   Memo1.Lines.Add('Button Status: ' + IntToStr(integer(cButtonStatus)));
  117.  
  118.  
  119.   if (integer(cButtonStatus) and 1) <> 0 then
  120.      cbLeft.checked := true
  121.   else
  122.      cbLeft.checked := false;
  123.  
  124.   if (integer(cButtonStatus) and 2) <> 0 then
  125.      cbMiddle.checked := true
  126.   else
  127.      cbMiddle.checked := false;
  128.  
  129.   if (integer(cButtonStatus) and 4) <> 0 then
  130.      cbRight.checked := true
  131.   else
  132.      cbRight.checked := false;
  133.  
  134.  
  135.   finally
  136.      FreeMem(pBuffer);
  137.    end;
  138.  
  139.  
  140. end;
  141.  
  142. procedure TForm1.FormCreate(Sender: TObject);
  143. begin
  144.     PrevWndProc:=Windows.WNDPROC(SetWindowLongPtr(Self.Handle,GWL_WNDPROC,PtrInt(@WndCallback)));
  145. end;
  146.  
  147. procedure TForm1.Timer1Timer(Sender: TObject);
  148. begin
  149.   // Don't need to do anything, just having an event is enough to cause the
  150.   // wm_input messages to be received.
  151. end;
  152.  
  153.  
  154.  
  155. procedure TForm1.bRegisterDeviceClick(Sender: TObject);
  156. var
  157.   nDevices    : LongWord;
  158.   listentries : Array of RAWINPUTDEVICELIST;
  159.   i           : integer;
  160.   pBuffer     : ^char;
  161.   lwBufferLength: LongWord;
  162.   iReturnedByteCount:integer;
  163.  
  164.   pRID_DEVICE_INFO : ^RID_DEVICE_INFO;
  165.   lwRID_DEVICE_INFO_Length : LongWord;
  166.  
  167.  
  168.  
  169.   pRAWINPUTDEVICE : ^RAWINPUTDEVICE;
  170.  
  171. begin
  172.   lwBufferLength := BUFFER_LENGTH;   // use a hardcoded length here because it's an easy way to handle the string for the device name (length not known ahead of time).
  173.   GetMem(pBuffer,lwBufferLength);
  174.  
  175.   lwRID_DEVICE_INFO_Length := sizeof(RID_DEVICE_INFO);
  176.   Memo1.Lines.Add('lwRID_DEVICE_INFO_Length : ' + IntToStr(lwRID_DEVICE_INFO_Length));
  177.   GetMem(pRID_DEVICE_INFO, lwRID_DEVICE_INFO_Length);
  178.  
  179.   Memo1.Lines.Add('get information about list');
  180.   if (GetRawInputDeviceList(nil, nDevices, sizeof(RAWINPUTDEVICELIST)) = 0) then
  181.   begin
  182.     Memo1.Lines.Add('found ' + IntToStr(nDevices) + ' devices');
  183.  
  184.     Memo1.Lines.Add('Set size of list');
  185.     SetLength(listentries, nDevices);
  186.  
  187.     if (GetRawInputDeviceList(@ListEntries[0], nDevices, sizeof(RAWINPUTDEVICELIST)) <> LongWord(-1) ) then
  188.     begin
  189.       for i := low(ListEntries) to High(ListEntries) do
  190.       begin
  191.         Memo1.Lines.Add('Line = ' + IntToStr(i) + '  handle = ' + IntToStr(listentries[i].hDevice) + '  Type = ' + IntToStr(listentries[i].dwType));
  192.  
  193.         case listentries[i].dwType of
  194.         RIM_TYPEHID:               Memo1.Lines.Add('Other');
  195.         RIM_TYPEKEYBOARD:          Memo1.Lines.Add('Keyboard');
  196.         RIM_TYPEMOUSE:             Memo1.Lines.Add('Mouse');
  197.         end;
  198.  
  199.         iReturnedByteCount := GetRawInputDeviceInfo(listentries[i].hDevice,RIDI_DEVICENAME,pBuffer,lwBufferLength);
  200.         if (iReturnedByteCount < 1) then
  201.            begin
  202.              Memo1.Lines.Add('Error: Buffer too small : RIDI_DEVICENAME');
  203.              exit;
  204.            end;
  205.         Memo1.Lines.Add(pBuffer + ' : ' + IntToStr(iReturnedByteCount));
  206.  
  207.  
  208.         iReturnedByteCount := GetRawInputDeviceInfo(listentries[i].hDevice,RIDI_DEVICEINFO,pRID_DEVICE_INFO,lwRID_DEVICE_INFO_Length);
  209.         if (iReturnedByteCount < 1) then
  210.            begin
  211.              Memo1.Lines.Add('Error: Buffer to small : RIDI_DEVICEINFO');
  212.              exit;
  213.            end;
  214.         Memo1.Lines.Add('RID_DEVICE_INFO size : ' + IntToStr(pRID_DEVICE_INFO^.cbSize));
  215.  
  216.         case pRID_DEVICE_INFO^.dwType of
  217.         RIM_TYPEHID:
  218.           begin
  219.             Memo1.Lines.Add('dwType : RIM_TYPEHID');
  220.             Memo1.Lines.Add('dwVendorId : ' + IntToStr(pRID_DEVICE_INFO^.hid.dwVendorId));
  221.             Memo1.Lines.Add('dwProductId : ' + IntToStr(pRID_DEVICE_INFO^.hid.dwProductId));
  222.             Memo1.Lines.Add('dwVersionNumber : ' + IntToStr(pRID_DEVICE_INFO^.hid.dwVersionNumber));
  223.             Memo1.Lines.Add('usUsagePage : ' + IntToStr(pRID_DEVICE_INFO^.hid.usUsagePage));
  224.             Memo1.Lines.Add('usUsage : ' + IntToStr(pRID_DEVICE_INFO^.hid.usUsage));
  225.           end;
  226.         RIM_TYPEKEYBOARD:
  227.           begin
  228.             Memo1.Lines.Add('dwType : RIM_TYPEKEYBOARD');
  229.  
  230.           end;
  231.         RIM_TYPEMOUSE:
  232.           begin
  233.             Memo1.Lines.Add('dwType : RIM_TYPEMOUSE');
  234.  
  235.           end;
  236.  
  237.         end;
  238.  
  239.         if listentries[i].dwType = RIM_TYPEHID then
  240.            if pRID_DEVICE_INFO^.hid.dwVendorId = 1523 then       // vendor id for infinity
  241.               if pRID_DEVICE_INFO^.hid.dwProductId = 255 then    // product id for usb foot pedal
  242.                  begin
  243.                    Memo1.Lines.Add('******************************************');
  244.                    Memo1.Lines.Add('Found It');
  245.                    Memo1.Lines.Add('******************************************');
  246.  
  247.                    GetMem(pRAWINPUTDEVICE,sizeof(RAWINPUTDEVICE));
  248.  
  249.                    pRAWINPUTDEVICE^.usUsagePage   := pRID_DEVICE_INFO^.hid.usUsagePage;
  250.                    pRAWINPUTDEVICE^.usUsage       := pRID_DEVICE_INFO^.hid.usUsage;
  251.                    pRAWINPUTDEVICE^.dwFlags       := 0;
  252.                    pRAWINPUTDEVICE^.hwndTarget    := self.Handle;
  253.  
  254.                    if not RegisterRawInputDevices(pRAWINPUTDEVICE,1,sizeof(RAWINPUTDEVICE))then
  255.                       begin
  256.                         Memo1.Lines.Add('Failed To Register HID');
  257.                         exit;
  258.                       end;
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.                    FreeMem(pRAWINPUTDEVICE);
  266.  
  267.                    break;
  268.                  end;
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.         Memo1.Lines.Add(' ');
  277.  
  278.  
  279.       end;
  280.     end
  281.     else Memo1.Lines.Add('error retreiving the list');
  282.  
  283.     SetLength(listentries, 0);
  284.   end
  285.   else Memo1.Lines.Add('error');
  286.  
  287.   FreeMem(pBuffer);
  288.   FreeMem(pRID_DEVICE_INFO);
  289. end;
  290.  
  291.  
  292. end.
  293.  
  294.  
  295.  
  296.  

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: no wm_input message until other messages are being sent
« Reply #1 on: November 14, 2016, 06:47:05 pm »
Code: Pascal  [Select][+][-]
  1. //...
  2.                    pRAWINPUTDEVICE^.dwFlags       := 0;
  3.                    pRAWINPUTDEVICE^.hwndTarget    := self.Handle;
  4. //...
Try pRAWINPUTDEVICE^.dwFlags := RIDEV_INPUTSINK;

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: no wm_input message until other messages are being sent
« Reply #2 on: November 14, 2016, 11:25:30 pm »
I have registered the raw device, and have set up a message loop that handles wm_input.

Why are you using SetWindowLongPtr() to subclass the Form's window?  You should be overriding the Form's virtual WndProc() method instead.

You should also override your Form's virtual InitializedWnd() method to call RegisterRawInputDevices().  That way, you can (re)register your current window whenever it is (re)created.  If your window ever gets recreated, you need to reregister the new window handle in order to continue receiving messages.

The problem I am having now is that the wm_input message is not being processed by my message loop until other messages (events) are being received. 

That implies that you are not managing your message loop correctly.  But you did not show that code.

Code: [Select]
pRAWINPUTDEVICE^.dwFlags       := 0;

By setting the dwFlags to 0, you will receive WM_INPUT messages only when your Form's window is in the foreground.  If you need to receive messages while the window is not in the foreground, you need to enable the RIDEV_INPUTSINK flag.

You should also consider enabling the RIDEV_DEVNOTIFY flag so you can receive WM_INPUT_DEVICE_CHANGE messages.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

dmudie

  • New member
  • *
  • Posts: 9
Re: no wm_input message until other messages are being sent
« Reply #3 on: November 15, 2016, 04:36:19 pm »
ASerge and Remy,

Thank you for your responses. 

I did look at the dwflags parameter, but was having other problems.  I never got back to reviewing them.  I tried using the RIDEV_INPUTSINK setting that you both suggested, but it did not change the behavior.  I will read through the documentation and look at all of the dwflag settings to see if I have missed something else.

Remy:

Thank you for your suggestion about using WndProc().  From my years ago Delphi days I was thinking about going this way... however, in doing research I found two posts. 

Starting with http://forum.lazarus.freepascal.org/index.php?topic=6062.0, Vincent describes having to hook the WndProc yourself.  I couldn't find any other references to this.  He also gives a link in the wiki that describes using the windows SetWindowLong function. 

I didn't get this working, but I found some sample code on a Delphi site that used SetWindowLongPtr, and it worked. 

I would love to override WndProc.  It seems a lot cleaner.  I tried doing this in response to your message, but it didn't work. 
Could you please explain what I am doing wrong or point me to some sample code?

Thanks,

David.


Code: Pascal  [Select][+][-]
  1.  
  2. unit umain;
  3.  
  4. {$mode OBJFPC}{$H+}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  10.   ExtCtrls, jwawinuser, windows, LMessages;
  11.  
  12. const
  13.   BUFFER_LENGTH =              255;
  14.  
  15.  
  16. type
  17.  
  18.   { TForm1 }
  19.  
  20.   TForm1 = class(TForm)
  21.     bRegisterDevice: TButton;
  22.     cbLeft: TCheckBox;
  23.     cbMiddle: TCheckBox;
  24.     cbRight: TCheckBox;
  25.     Memo1: TMemo;
  26.     Panel1: TPanel;
  27.     Timer1: TTimer;
  28.  
  29.     procedure bRegisterDeviceClick(Sender: TObject);
  30.     procedure FormCreate(Sender: TObject);
  31.     procedure Timer1Timer(Sender: TObject);
  32.   private
  33.     { private declarations }
  34.  
  35.   protected
  36.     procedure WndProc ( var Msg: TLMessage ) ; override;
  37.  
  38.   public
  39.     { public declarations }
  40.     function WMInput(wParam: WParam; lParam: LParam):LRESULT;
  41.   end;
  42.  
  43. var
  44.   Form1: TForm1;
  45.  
  46. implementation
  47.  
  48. {$R *.lfm}
  49.  
  50.  
  51. //var
  52. //  PrevWndProc:windows.WNDPROC;
  53.  
  54.  
  55.  
  56. {function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam;
  57.   lParam: LParam): LRESULT; stdcall;
  58.   // replace the message loop in order to handle the WM_INPUT message
  59. begin
  60.   case uMsg of
  61.   WM_INPUT:
  62.     begin
  63. //      Form1.Memo1.Lines.Add('Beep');
  64.  
  65.       result := Form1.WMInput(wParam,lParam);
  66.  //     result := DefWindowProc(Ahwnd,uMsg,wParam,LParam);
  67.      end;
  68.   end;
  69.  
  70.   // if the message is not a WM_INPUT, then call the default message loop to handle it
  71.   Result := CallWindowProc(PrevWndProc, Ahwnd, uMsg, WParam, LParam);
  72. end;  }
  73.  
  74.  
  75. { TForm1 }
  76.  
  77.  
  78. procedure TForm1.WndProc ( var Msg: TLMessage ) ;
  79. begin
  80.   if Msg.msg = WM_INPUT then
  81.      begin
  82.        Msg.Result := WMInput(Msg.wParam,Msg.lParam);
  83.      end;
  84.  
  85.   inherited WndProc(Msg);
  86. end;
  87.  
  88. function TForm1.WMInput(wParam: WParam; lParam: LParam):LRESULT;
  89. var
  90. //  pBuffer     : ^RAWINPUT;
  91.   pBuffer     : ^char;
  92.   lwBufferLength: LongWord;
  93.   iBytesCopied: integer;
  94.  
  95.   cButtonStatus: char;
  96.  
  97. begin
  98.   Result := 0;
  99.  
  100.   lwBufferLength := SizeOf(RAWINPUTHEADER);
  101.  
  102.   if GetRawInputData(HRAWINPUT(lParam),RID_INPUT,NIL,lwBufferLength,SizeOf(RAWINPUTHEADER)) <> 0 then
  103.      begin
  104.        Memo1.Lines.Add('Error Getting Buffer Size GetRawInputData(hToRawInput,RID_HEADER,pBuffer,lwBufferLength,0)');
  105.        exit;
  106.      end;
  107.  
  108.  
  109.   GetMem(pBuffer,lwBufferLength);
  110.  
  111.   try
  112.  
  113.      iBytesCopied := GetRawInputData(HRAWINPUT(lParam),RID_INPUT,pBuffer,lwBufferLength,SizeOf(RAWINPUTHEADER));
  114.  
  115.      if  iBytesCopied < 1 then
  116.      begin
  117.        exit;
  118.      end;
  119.  
  120.  
  121.   cButtonStatus := (pBuffer+25)^;
  122.   Memo1.Lines.Add('Button Status: ' + IntToStr(integer(cButtonStatus)));
  123.  
  124.  
  125.   if (integer(cButtonStatus) and 1) <> 0 then
  126.      cbLeft.checked := true
  127.   else
  128.      cbLeft.checked := false;
  129.  
  130.   if (integer(cButtonStatus) and 2) <> 0 then
  131.      cbMiddle.checked := true
  132.   else
  133.      cbMiddle.checked := false;
  134.  
  135.   if (integer(cButtonStatus) and 4) <> 0 then
  136.      cbRight.checked := true
  137.   else
  138.      cbRight.checked := false;
  139.  
  140.  
  141.   finally
  142.      FreeMem(pBuffer);
  143.    end;
  144.  
  145.  
  146. end;
  147.  
  148. procedure TForm1.FormCreate(Sender: TObject);
  149. begin
  150. //    PrevWndProc:=Windows.WNDPROC(SetWindowLongPtr(Self.Handle,GWL_WNDPROC,PtrInt(@WndCallback)));
  151. end;
  152.  
  153. procedure TForm1.Timer1Timer(Sender: TObject);
  154. begin
  155.   // Don't need to do anything, just having an event is enough to cause the
  156.   // wm_input messages to be received.
  157. end;
  158.  
  159.  
  160.  
  161. procedure TForm1.bRegisterDeviceClick(Sender: TObject);
  162. var
  163.   nDevices    : LongWord;
  164.   listentries : Array of RAWINPUTDEVICELIST;
  165.   i           : integer;
  166.   pBuffer     : ^char;
  167.   lwBufferLength: LongWord;
  168.   iReturnedByteCount:integer;
  169.  
  170.   pRID_DEVICE_INFO : ^RID_DEVICE_INFO;
  171.   lwRID_DEVICE_INFO_Length : LongWord;
  172.  
  173.  
  174.  
  175.   pRAWINPUTDEVICE : ^RAWINPUTDEVICE;
  176.  
  177. begin
  178.   lwBufferLength := BUFFER_LENGTH;   // use a hardcoded length here because it's an easy way to handle the string for the device name (length not known ahead of time).
  179.   GetMem(pBuffer,lwBufferLength);
  180.  
  181.   lwRID_DEVICE_INFO_Length := sizeof(RID_DEVICE_INFO);
  182.   Memo1.Lines.Add('lwRID_DEVICE_INFO_Length : ' + IntToStr(lwRID_DEVICE_INFO_Length));
  183.   GetMem(pRID_DEVICE_INFO, lwRID_DEVICE_INFO_Length);
  184.  
  185.   Memo1.Lines.Add('get information about list');
  186.   if (GetRawInputDeviceList(nil, nDevices, sizeof(RAWINPUTDEVICELIST)) = 0) then
  187.   begin
  188.     Memo1.Lines.Add('found ' + IntToStr(nDevices) + ' devices');
  189.  
  190.     Memo1.Lines.Add('Set size of list');
  191.     SetLength(listentries, nDevices);
  192.  
  193.     if (GetRawInputDeviceList(@ListEntries[0], nDevices, sizeof(RAWINPUTDEVICELIST)) <> LongWord(-1) ) then
  194.     begin
  195.       for i := low(ListEntries) to High(ListEntries) do
  196.       begin
  197.  
  198.         iReturnedByteCount := GetRawInputDeviceInfo(listentries[i].hDevice,RIDI_DEVICENAME,pBuffer,lwBufferLength);
  199.         if (iReturnedByteCount < 1) then
  200.            begin
  201.              Memo1.Lines.Add('Error: Buffer too small : RIDI_DEVICENAME');
  202.              exit;
  203.            end;
  204.         Memo1.Lines.Add(pBuffer + ' : ' + IntToStr(iReturnedByteCount));
  205.  
  206.  
  207.         iReturnedByteCount := GetRawInputDeviceInfo(listentries[i].hDevice,RIDI_DEVICEINFO,pRID_DEVICE_INFO,lwRID_DEVICE_INFO_Length);
  208.         if (iReturnedByteCount < 1) then
  209.            begin
  210.              Memo1.Lines.Add('Error: Buffer to small : RIDI_DEVICEINFO');
  211.              exit;
  212.            end;
  213.  
  214.         if listentries[i].dwType = RIM_TYPEHID then
  215.            if pRID_DEVICE_INFO^.hid.dwVendorId = 1523 then       // vendor id for infinity
  216.               if pRID_DEVICE_INFO^.hid.dwProductId = 255 then    // product id for usb foot pedal
  217.                  begin
  218.                    Memo1.Lines.Add('******************************************');
  219.                    Memo1.Lines.Add('Found It');
  220.                    Memo1.Lines.Add('******************************************');
  221.  
  222.                    GetMem(pRAWINPUTDEVICE,sizeof(RAWINPUTDEVICE));
  223.  
  224.                    pRAWINPUTDEVICE^.usUsagePage   := pRID_DEVICE_INFO^.hid.usUsagePage;
  225.                    pRAWINPUTDEVICE^.usUsage       := pRID_DEVICE_INFO^.hid.usUsage;
  226. //                   pRAWINPUTDEVICE^.dwFlags       := 0;
  227.                    pRAWINPUTDEVICE^.dwFlags := RIDEV_INPUTSINK;
  228.                    pRAWINPUTDEVICE^.hwndTarget    := self.Handle;
  229.  
  230.                    if not RegisterRawInputDevices(pRAWINPUTDEVICE,1,sizeof(RAWINPUTDEVICE))then
  231.                       begin
  232.                         Memo1.Lines.Add('Failed To Register HID');
  233.                         exit;
  234.                       end;
  235.  
  236.  
  237.                    FreeMem(pRAWINPUTDEVICE);
  238.  
  239.                    break;
  240.                  end;
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.         Memo1.Lines.Add(' ');
  249.  
  250.  
  251.       end;
  252.     end
  253.     else Memo1.Lines.Add('error retreiving the list');
  254.  
  255.     SetLength(listentries, 0);
  256.   end
  257.   else Memo1.Lines.Add('error');
  258.  
  259.   FreeMem(pBuffer);
  260.   FreeMem(pRID_DEVICE_INFO);
  261. end;
  262.  
  263.  
  264. end.
  265.  
  266.  
  267.  

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: no wm_input message until other messages are being sent
« Reply #4 on: November 15, 2016, 08:19:50 pm »
Thank you for your suggestion about using WndProc().  From my years ago Delphi days I was thinking about going this way... however, in doing research I found two posts. 

Starting with http://forum.lazarus.freepascal.org/index.php?topic=6062.0, Vincent describes having to hook the WndProc yourself.

At the very bottom of that same discussion, oxen said:

In the version of Lazarus that I am using (0.9.30 FPC 2.5.1 SVN 29251) custom windows messages seem to be working the Delphi way

And he shows an example using the 'message' directive to handle WM_HOTKEY.  The same kind of thing that mauzer_tim documented as not working in 0.9.26.

So, try seeing if applying the 'message' directive to your WMInput() method can receive the WM_INPUT messages.

On the other hand, I see posts that say only a few Window messages can be caught with the 'message' directive, so maybe WM_INPUT will not work that way after all.

I didn't get this working, but I found some sample code on a Delphi site that used SetWindowLongPtr, and it worked. 

If you are going to resort to subclassing the window procedure, at the very least you should use SetWindowSubclass() instead (see Safer subclassing).

Either way, like I said earlier, the OnCreate event is a bad place to perform the subclassing.  Try overriding InitializedWnd() instead.  That is also a good place to call RegisterRawInputDevices() as well.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

dmudie

  • New member
  • *
  • Posts: 9
Re: no wm_input message until other messages are being sent
« Reply #5 on: November 22, 2016, 04:10:20 pm »
Okay, it's taken me a while to get things working.  Thanks for all of your help.

 

TinyPortal © 2005-2018