Recent

Author Topic: Can not get the Key Scan Code - only the virtual key code  (Read 1512 times)

thehidden

  • Jr. Member
  • **
  • Posts: 57
  • Freelancer
Can not get the Key Scan Code - only the virtual key code
« on: June 30, 2020, 02:07:49 pm »
Hi,

For an Application I have set KeyPreview := true on all forms.

I have tried some ways to get the keyboard scan code because I need to select if the return key or the enter key ad the number pad has been pressed.

WM_KEYDOWN shows nothing.
The sample from GetMem does not compile with Lazarus and 64bit.

Any idea how to get the different scan codes? The virtual key codes (VK_RETURN) are identical.

Thank you.
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

jamie

  • Hero Member
  • *****
  • Posts: 3641
« Last Edit: June 30, 2020, 02:57:22 pm by jamie »
The only true wisdom is knowing you know nothing

thehidden

  • Jr. Member
  • **
  • Posts: 57
  • Freelancer
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #2 on: June 30, 2020, 03:25:16 pm »

https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes


The return keys are the same I believe
This are the virtual key codes.

There are also Scan codes from the keyboard controller. There is "VK_Return" for the Return Key and "VK_Return + Enhanced Key" for the Enter Key at the Num Pad. The Member GetMem has made 2015 a demo for catching it, but this does not work with x64 compilation.
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

jamie

  • Hero Member
  • *****
  • Posts: 3641
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #3 on: June 30, 2020, 03:32:51 pm »
Please show a very simple block of code you are using..

I can capture the vk's of the numpad they are in the list I showed you.

There isn't much of in the way of capturing keys are the hardware level.

You can also use GetKeyBoardState which captures all 255 keys at once but still, that isn't going to help you much..

So please show some minimum example block you are using..

btw, you need to include LCLtype and WINDOWS unit depending on how deep you go
The only true wisdom is knowing you know nothing

thehidden

  • Jr. Member
  • **
  • Posts: 57
  • Freelancer
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #4 on: June 30, 2020, 03:51:09 pm »
The following code is only a part of the complete application. Some units are in use for other functions...

Code: Pascal  [Select][+][-]
  1. uses LCLType, Windows,   LMessages, LCLIntf;
  2.  
  3. ....
  4.  
  5. procedure TForm1.FormKeyUp(Sender : TObject; var Key : Word; Shift : TShiftState);
  6. var
  7.    key1 : string;   //further usage in the application
  8. begin
  9.    case key of
  10.       VK_ESCAPE: key1 := 'ESC';
  11.       VK_UP: key1 := 'UP';
  12.       VK_F1: key1 := 'F 1';
  13.       VK_NUMLOCK: key1 := 'NUMLOCK';
  14.       VK_SCROLL: key1 := 'SCROLLOCK';
  15.       VK_LCL_CAPSLOCK: key1 := 'CAPSLOCK';
  16.       VK_SNAPSHOT: key1 := 'PRINT';
  17.       VK_RCONTROL: key1 := 'CTRL R';
  18.       VK_PAUSE: key1 := 'PAUSE';
  19.       VK_LCL_LALT: key1 := 'L ALT';
  20.       VK_LCL_RALT: key1 := 'R ALT';
  21.       VK_LCL_ALT: key1 := 'ALT';
  22.       VK_LWIN: key1 := 'LWIN';
  23.       VK_RWIN: key1 := 'RWIN';
  24.       VK_TAB: key1 := '.TAB.';
  25.       VK_END: key1 := 'END';
  26.       VK_HOME: key1 := 'Home/Pos1';
  27.       VK_BACK: key1 := 'BACKSPACE';
  28.       VK_DELETE: key1 := 'Delete';
  29.       VK_INSERT: key1 := 'Insert';
  30.       VK_RETURN: key1 := 'Return-Main';
  31. //    VK_ENTER: key1 := 'Enter - Numpad';   // NOT WORKING!!!!
  32.       VK_NUMPAD5: key1 :='Num Pad 5';
  33.       VK_NEXT: key1 := 'PG DOWN';
  34.       VK_PRIOR: key1 :='PG UP';
  35.    end;                                                                  
  36. end;
  37.  

I need a solution for Line 31, because I need to know if the Return Key or Enter Key has been pressed. This will start two difference functions.

There is an example from 2007, but this is for Delphi and gives no result with keypreview := true.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.WMKeyDown(var Message: TWMKeyDown);
  2. begin
  3.   inherited;
  4.   case Message.CharCode of
  5.     VK_RETURN: // ENTER pressed
  6.       if (Message.KeyData and $1000000 <> 0) then
  7.         // Test bit 24 of lParam
  8.         ShowMessage('ENTER on numeric keypad')
  9.       else
  10.         ShowMessage('ENTER on Standard keyboard');
  11.   end;
  12. end;
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

rvk

  • Hero Member
  • *****
  • Posts: 4327
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #5 on: June 30, 2020, 04:30:04 pm »
There is an example from 2007, but this is for Delphi and gives no result with keypreview := true.
I don't think you can catch the numpad enter with OnKeyDown.
And definitely not with OnKeyUp (which is even less flexible).

But what's wrong with catching WM_KEYDOWN yourself?
The problem is that you can't do it the same way as Delphi.
In Delphi you can just add "message WM_KEYDOWN" in the implementation and catch that message.
In Lazarus you can't catch non-user messages like this.
See https://wiki.freepascal.org/Win32/64_Interface#Processing_non-user_messages_in_your_window

You'll need to put in a hook to catch those.

See for an example here https://forum.lazarus.freepascal.org/index.php/topic,38889.msg265561.html#msg265561

GetMem

  • Hero Member
  • *****
  • Posts: 3757
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #6 on: June 30, 2020, 04:30:37 pm »
@thehidden
Quote
The Member GetMem has made 2015 a demo for catching it, but this does not work with x64 compilation.
Did you try $MODE DELPHI? I cannot test now, I'm not in front of my computer.

thehidden

  • Jr. Member
  • **
  • Posts: 57
  • Freelancer
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #7 on: June 30, 2020, 04:43:21 pm »
@thehidden
Quote
The Member GetMem has made 2015 a demo for catching it, but this does not work with x64 compilation.
Did you try $MODE DELPHI? I cannot test now, I'm not in front of my computer.

Error Message with {$mode objfpc}
umain.pas(141,77) Error: Incompatible type for arg no. 2: Got "<address of function(LongInt;Int64;Int64):LongInt;StdCall>", expected "<procedure variable type of function(LongInt;Int64;Int64):Int64;StdCall>"

With {$mode delphi} it compiles completely but...
keyhook shows 0xc1 for return and enter
keypress does not show if return or enter is pressed and each new character has position 1 at line 1
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

GetMem

  • Hero Member
  • *****
  • Posts: 3757
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #8 on: June 30, 2020, 04:53:10 pm »
This with mode delphi:
https://forum.lazarus.freepascal.org/index.php/topic,40752.msg281697.html#msg281697

PS: If does not work, I cannot help you now.

jamie

  • Hero Member
  • *****
  • Posts: 3641
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #9 on: June 30, 2020, 04:57:42 pm »
There are issues with LCL not allowing to override the MESSAGES property... This should be corrected but it will never happen....

 The Over ridden messages should be processed first before user messages gets called, this isn't the case however,....

 Here is a example of the case … its one key stroke in the back.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Windows,Classes, SysUtils, Forms, Controls, Graphics, Dialogs,lcltype;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  16.   private
  17.      OEMScanCode:Lparam;
  18.   public
  19.     procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
  20.    procedure WMKeyUp(var Message: TWMKeyUP); message WM_KEYUP;
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. { TForm1 }
  31. procedure TForm1.WMKeyDown(var Message: TWMKeyDown);
  32. Begin
  33.   OEMSCANCode := Message.KeyData;
  34.   inherited;
  35.   end;
  36. procedure TForm1.WMKeyUp(var Message: TWMKeyUp);
  37. Begin
  38.   OEMSCANCode := Message.KeyData;
  39.   inherited;
  40.   end;
  41.  
  42. procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
  43.   );
  44. begin
  45.  If  (key=VK_Return) Then If (OEMSCANCode and $1000000 <> 0) then Caption := 'VK_ENTER' else
  46.    caption := 'VK_RETURN'
  47.     else Caption := 'Not Interested';
  48. end;
  49.  
  50. end.
  51.  
  52.  
The only true wisdom is knowing you know nothing

winni

  • Hero Member
  • *****
  • Posts: 1897
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #10 on: June 30, 2020, 05:01:11 pm »
Hi!

Have a look at getmems LowLevelKeyboadHook in this forum:

https://forum.lazarus.freepascal.org/index.php/topic,40752.msg281697.html#msg281697

Winni

thehidden

  • Jr. Member
  • **
  • Posts: 57
  • Freelancer
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #11 on: June 30, 2020, 05:07:09 pm »
Hi!

Have a look at getmems LowLevelKeyboadHook in this forum:

https://forum.lazarus.freepascal.org/index.php/topic,40752.msg281697.html#msg281697

Winni
Tested. Result is always VK_Return
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

thehidden

  • Jr. Member
  • **
  • Posts: 57
  • Freelancer
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #12 on: June 30, 2020, 05:19:07 pm »
Quote
There are issues with LCL not allowing to override the MESSAGES property... This should be corrected but it will never happen....

 The Over ridden messages should be processed first before user messages gets called, this isn't the case however,....

 Here is a example of the case … its one key stroke in the back.

I have have copied everything complete, it shows on my keyboard only Return and never enter, regardless what key I am pressing.
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

GetMem

  • Hero Member
  • *****
  • Posts: 3757
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #13 on: June 30, 2020, 05:28:52 pm »
@ thehidden
Quote
Tested. Result is always VK_Return
You should also check flags in the structure. See here for more details(bits/description):
https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-kbdllhookstruct

Quote
Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
« Last Edit: June 30, 2020, 06:06:54 pm by GetMem »

jamie

  • Hero Member
  • *****
  • Posts: 3641
Re: Can not get the Key Scan Code - only the virtual key code
« Reply #14 on: June 30, 2020, 05:47:02 pm »
The example I posted does work for me, its just one stroke behind and that's the fault of the LCL handling it in the wrong order.

 Oh well...

The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018