ŁukaszDe 38 Posted December 6, 2019 Hello In application I need to know is pressed any key on keyboard. On keyboard we have two keys INSERT. one normal and another on Numpad. The second one is working when Num Lock is turned on and need Shift Key pressed. The problem is with INSERT on Numpad. When you press SHIFT and 0 on numpad then GetKeyState(VK_INSERT) result is ok, key pressed. But when you release SHIFT then above function still result is wrong because now preseed is 0, no INSERT. Function result is < 0, which means the key is still pressed. If you try react in FormKeyUp and FormKeyDown then will not appear event for KeyUp(Key = 45) INSERT... Key 45 (INSERT) left pressed, even when we release numPad 0. Example code: program keytest; {$APPTYPE CONSOLE} {$R *.res} uses Windows, System.SysUtils; var Key: Integer; begin try repeat if (GetKeyState(VK_INSERT) < 0) then Writeln('INSERT') else Writeln('0'); until True; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Share this post Link to post
Rollo62 536 Posted December 6, 2019 Maybe a small Sleep(200); in the repeat-until loop may help the OS to process the messageloop ? Share this post Link to post
ŁukaszDe 38 Posted December 10, 2019 No. You can close application and run again and will be information that INSERT is pressed. Share this post Link to post
Stefan Glienke 2002 Posted December 10, 2019 GetKeyState and related WinAPI functions are broken with Numlock enabled - and you are not the only one suffering from this defect if you google for numpad shift stuck If you release the shift key first it never sees the keyup of the insert key (which the shift key turned the numpad 0 key to). You have to use other ways to do that Share this post Link to post
Attila Kovacs 629 Posted December 10, 2019 I can't see anything broken. SHIFT overrides NumLock and CapsLock. That means, with NumLock ON pressing SHIFT + 0 = pressing insert. Releasing SHIFT means, you are holding the 0 key, releasing 0 means you are releasing the 0 key, and not Insert. That's how windows works. Share this post Link to post
Gustav Schubert 25 Posted December 11, 2019 So, it is best to use KeyDown and KeyUp in FMX to determine if any of the two insert keys is currently down? implementation {$R *.fmx} uses Windows; var IsInsertPressed: Boolean; procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); begin case key of 45: begin IsInsertPressed := True; UpdateCaption; end; end; end; procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); begin case key of 45: begin IsInsertPressed := False; UpdateCaption; end; end; case KeyChar of '0': begin IsInsertPressed := False; end; end; UpdateCaption; end; procedure TForm1.UpdateCaption; begin if IsInsertPressed then Caption := 'INSERT' else Caption := '0'; end; end. Share this post Link to post
Vandrovnik 214 Posted December 11, 2019 15 hours ago, Attila Kovacs said: I can't see anything broken. SHIFT overrides NumLock and CapsLock. That means, with NumLock ON pressing SHIFT + 0 = pressing insert. Releasing SHIFT means, you are holding the 0 key, releasing 0 means you are releasing the 0 key, and not Insert. That's how windows works. I think it is broken - windows is reporting INSERT down, but it is not. In fact as soon as he releases Shift, he is not pressing Insert anymore, so there should be Shift-up, Insert-up, Zero-down. Share this post Link to post
Gustav Schubert 25 Posted December 11, 2019 VK_INSERT tests a virtual key not a real key, this is how I understand it after testing. Windows is reporting the insert STATE - on or off - when you call GetKeyState, possible return values: 0, -1, -127, or -128. You cannot even tell which of the insert keys or key combinations were used to toggle the state. In VCL, FormKeyPress triggers for KeyDown only, and FormKeyUp does not respond to the numpad numbers at all? ( In FMX, you can use FormKeyUp to successfully detect the '0' up character and know that the key was lifted. ) Share this post Link to post
Gustav Schubert 25 Posted December 11, 2019 (edited) 22 hours ago, Stefan Glienke said: You have to use other ways to do that, Using ScanCode perhaps, in VCL? unit Unit1; interface uses Winapi.Windows, Winapi.Messages, Vcl.Forms; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private ScanCode: Word; public procedure WMKeyDown(var Msg: TMessage); message WM_KEYDOWN; procedure WMKeyUp(var Msg: TMessage); message WM_KEYUp; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin ScanCode := Lo(MapVirtualKey(VK_INSERT, 0)); end; procedure TForm1.WMKeyDown(var Msg: TMessage); var w: Word; b: Byte; begin w := Msg.LParamHi; b := LoByte(w); if b = ScanCode then Caption := 'down'; inherited; end; procedure TForm1.WMKeyUp(var Msg: TMessage); var w: Word; b: Byte; begin w := Msg.LParamHi; b := LoByte(w); if b = ScanCode then Caption := 'up'; inherited; end; end. Edited December 11, 2019 by Gustav Schubert Share this post Link to post