1

I have made an application in Delphi that handles some defined system wide hotkeys, works perfectly. However, for some hotkey functionality I have to trigger/simulate some keyboard strokes such as ALT+ENTER. This works great when the user releases the hotkey keys directly, but when the keys are still pressed by the user the keyboard simulation fail.

Is there a way (with windows API) to check if all keys are released before I process a keyboard simulation?

Codebeat
  • 6,501
  • 6
  • 57
  • 99
  • Why not use an Action Manager which has built-in hotkey support? Or are you wanting to capture these events outside your application? On the other hand, we would need to see how your current code works to be able to advise how to continue. – Jerry Dodge Aug 21 '15 at 15:39
  • Faking input is a tricky business. Usually best avoided. – David Heffernan Aug 21 '15 at 16:21
  • Thanks for the comments. This question is related to this question: http://stackoverflow.com/questions/32062929/directx-full-screen-window-to-windowed-by-window-handle-with-use-windows-api-fun . If you know to how to manage a DirectX window, no keys are required. In this is case is not tricky because I can check the state of the window. If ALT+ENTER is not applied, nothing happens. Changed the code allot already. And yes, the hotkeys are processed outside the app so action manager is not useful. But why all these concerns? Please answer my question, I know what I'm doing and why. – Codebeat Aug 21 '15 at 18:20
  • The question is: Is it possible with use of Windows API to check te state of the keys of the keyboard. I found getKeyboardState already but don't how to use it. Cannot find an useful example. – Codebeat Aug 21 '15 at 18:23
  • I don't understand some people of stackoverflow, why downvote, what's wrong with this question? Please, when you downvote leave a comment why you downvoted. In this situation it is frustrating and I cannot do anything to improve the question because I don't know what's wrong with it. There where upvotes anyway, so I think some people had a bad hair day? I dunno. – Codebeat Aug 22 '15 at 00:36
  • Like all online communities, you can go crazy wondering why. Just get what you came for and hope everyone else did too. EDIT: and don't care too much about your reputation, much of it is beyond your control. – David Ching Aug 22 '15 at 00:42
  • Thank you @DavidChing for understanding. – Codebeat Aug 22 '15 at 00:43
  • @DavidChing: I don't care about my reputation, I trying to understand what's going on, what's wrong. That's all I want to know ;-) . – Codebeat Aug 22 '15 at 01:01
  • When you find out, let me know! I've stopped trying to understand some people here. – David Ching Aug 22 '15 at 01:11
  • @DavidChing: I think some people might think it's an impossible task to realize but it's not. The answer is already there, see also accepted answer. – Codebeat Aug 23 '15 at 20:28

2 Answers2

0

Use GetAsyncKeyState as this API reflects the true current state of the keyboard, and not when your app last called GetMessage. Just write a loop that calls it for each value between 0 and 0xFF.

If the most significant bit is set, the key is down

David Ching
  • 1,903
  • 17
  • 21
0

Thanks go to @David Ching and @David Heffernan (two Davids!) The solution is not only to test keyboard input but also mouse input or better, the state of input devices.

The mouse is also included because of:

  { Virtual Keys, Standard Set }
  VK_LBUTTON = 1;
  VK_RBUTTON = 2;
  VK_MBUTTON = 4;  { NOT contiguous with L & RBUTTON }

So, if don't want to test mousebuttons you have to exclude it from the loop. It's better to check these also because there are hotkeys that must be used with the mouse. It's better to check everything on input is idle.

function isUserInputDevicesInUse() : Boolean;  // Keyboard pressed / mouse pressed?
var
 i            : LongInt;

begin
 i:=256;
 Result:=FALSE;

 while( i > 0 ) and ( NOT Result ) do
 begin
  Dec( i );
  Result:=( GetAsyncKeyState(i) < 0 );
 end;
end;

function isUserInputDevicesIdle() : Boolean;
begin
 Result:=NOT isUserInputDevicesInUse();
end;
Codebeat
  • 6,501
  • 6
  • 57
  • 99