Recent

Author Topic: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?  (Read 473 times)

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
I'm developing an app which needs to monitor some keys via AddOnUserInputHandler.

For instance in the event below if the message is LM_KEYDOWN how would I know which actual key was pressed?

procedure InputHandler(Sender:TObject; Msg:Cardinal);

If the VK_XXX code embedded in the LM_KEYDOWN value or does it have to be retrieved from somewhere else?

Would that have to come from the Application itself?
Lazarus 3.0/FPC 3.2.2

cdbc

  • Hero Member
  • *****
  • Posts: 1678
    • http://www.cdbc.dk
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #1 on: October 08, 2024, 11:54:22 am »
Hi
The 'Key' value would be in either WParam or LParam of the message...
After all, it's just a numeric value.
Just my 2 cents worth
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Thaddy

  • Hero Member
  • *****
  • Posts: 16201
  • Censorship about opinions does not belong here.
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #2 on: October 08, 2024, 12:00:21 pm »
It is stored in wparam. lparam stores additional information such as repeat counts and scan code.
See msdn:
https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-keydown

That info is in the TMsg record, but it depends on the message on how to interpret it.
« Last Edit: October 08, 2024, 12:02:00 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #3 on: October 08, 2024, 12:01:46 pm »
Hi
The 'Key' value would be in either WParam or LParam of the message...
After all, it's just a numeric value.
Just my 2 cents worth
Regards Benny

Msg is a plain Cardinal. Are WParam and LParam functions, or do I have to cast Msg to some other type to obtain the Key?
Lazarus 3.0/FPC 3.2.2

Thaddy

  • Hero Member
  • *****
  • Posts: 16201
  • Censorship about opinions does not belong here.
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #4 on: October 08, 2024, 12:04:50 pm »
msg is not a plain cardinal it is a record. In the case of a Cardinal, that is only true if it is 32 bit pointer to msg, in the case the message is a pointer, which it isn't, it is not cardinal but prtuint.
You did not read my link....which is slightly annoying late in the morning. I' ll have some lunch.
Code: C  [Select][+][-]
  1. typedef struct tagMSG {
  2.   HWND   hwnd;      // Handle to the window that receives the message
  3.   UINT   message;   // Message identifier
  4.   WPARAM wParam;    // Additional message information (depends on the message)
  5.   LPARAM lParam;    // Additional message information (depends on the message)
  6.   DWORD  time;      // Time at which the message was posted
  7.   POINT  pt;        // Cursor position in screen coordinates when the message was posted
  8.   DWORD  lPrivate;  // Reserved for use by the system
  9. } MSG, *PMSG;
Or look in the windows unit to see the pascal representation, which is the same.
« Last Edit: October 08, 2024, 12:08:03 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Sieben

  • Sr. Member
  • ****
  • Posts: 367
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #5 on: October 08, 2024, 12:08:14 pm »
@vcflists: Since you still seem to be working on the same issue I wonder if you read this reply...?
Lazarus 2.2.0, FPC 3.2.2, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

Thaddy

  • Hero Member
  • *****
  • Posts: 16201
  • Censorship about opinions does not belong here.
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #6 on: October 08, 2024, 12:16:17 pm »
At second glance, it may be that not the whole record is passed.
I will have a look at third glance, because that would maybe be a bug since it suggests you have not all message information. and that is bad...
Anyway for the answer to LM_KEYDOWN the answer should be correct.

better solution is along these lines:
Code: Pascal  [Select][+][-]
  1. type
  2.   TForm1 = class(TForm)
  3.     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  4.   private
  5.     { private declarations }
  6.   public
  7.     { public declarations }
  8.   end;
  9.  
  10. var
  11.   Form1: TForm1;
  12.  
  13. procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  14. begin
  15.   if Key = VK_K then
  16.     ShowMessage('K key pressed!');
  17. end;
that may be sufficient. You can also apply this to controls instead of the form, of course.
« Last Edit: October 08, 2024, 12:21:16 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #7 on: October 08, 2024, 12:58:22 pm »
msg is not a plain cardinal it is a record. In the case of a Cardinal, that is only true if it is 32 bit pointer to msg, in the case the message is a pointer, which it isn't, it is not cardinal but prtuint.
You did not read my link....which is slightly annoying late in the morning. I' ll have some lunch.
Code: C  [Select][+][-]
  1. typedef struct tagMSG {
  2.   HWND   hwnd;      // Handle to the window that receives the message
  3.   UINT   message;   // Message identifier
  4.   WPARAM wParam;    // Additional message information (depends on the message)
  5.   LPARAM lParam;    // Additional message information (depends on the message)
  6.   DWORD  time;      // Time at which the message was posted
  7.   POINT  pt;        // Cursor position in screen coordinates when the message was posted
  8.   DWORD  lPrivate;  // Reserved for use by the system
  9. } MSG, *PMSG;
Or look in the windows unit to see the pascal representation, which is the same.

Apologies for upsetting your mood just when you want to have some reinforcement.

This is the type used in the user input event.

Code: Pascal  [Select][+][-]
  1. type TOnUserInputEvent = procedure(
  2.   Sender: TObject;
  3.   Msg: Cardinal
  4. ) of object;
  5.  

I'm also using Linux though I suspect the Linux events may have been remapped to make them fit with the Windows model.

There is an example here - https://forum.lazarus.freepascal.org/index.php/topic,27980.msg173912.html#msg173912

and another from - http://lazarusroad.blogspot.com/2011/07/make-generic-control-behaves-like.html

Code: Pascal  [Select][+][-]
  1. procedure TMyPanel.UserInputHandler(Sender: TObject; Msg: Cardinal);
  2. var
  3.  AControl: TControl;
  4. begin
  5.  case Msg of
  6.    LM_LBUTTONDOWN, LM_LBUTTONDBLCLK, LM_RBUTTONDOWN, LM_RBUTTONDBLCLK,
  7.    LM_MBUTTONDOWN, LM_MBUTTONDBLCLK, LM_XBUTTONDOWN, LM_XBUTTONDBLCLK:
  8.    begin
  9.      AControl := Application.MouseControl;
  10.      if (AControl <> Self) and not IsParentOf(AControl) then
  11.        Visible := False;
  12.    end;
  13.  end;
  14. end;
  15.  

I have a feeling in that the event may be too  high level or I may have to cast it or treat as a pointer to something else, or get some additional info from the Application object.

In any case I've noticed an AddOnKeyDownHandler event which may be more suitable for this problem.
« Last Edit: October 08, 2024, 01:11:16 pm by vfclists »
Lazarus 3.0/FPC 3.2.2

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #8 on: October 08, 2024, 01:06:17 pm »
@vcflists: Since you still seem to be working on the same issue I wonder if you read this reply...?

That part of the problem is functionally complete. I put back the OnKeyXXX events into a subclass of TPanel, but they are not actually needed for the event I want to trap as key events on panels are usually caught by the controls placed on them.

I originally handled the response in the form's KeyPreview event but I'm now moving it in a separate component.
Lazarus 3.0/FPC 3.2.2

Sieben

  • Sr. Member
  • ****
  • Posts: 367
Re: How do you extract the VK_XXX code when you receive an LM_KEYDOWN event?
« Reply #9 on: October 08, 2024, 03:37:38 pm »
Another one you might want to have a look at if you didn't already: LCL Key Handling.
Lazarus 2.2.0, FPC 3.2.2, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

 

TinyPortal © 2005-2018