Physical Key State

2020-06-29 23:13发布

The two key-state functions in the WIndows API, GetKeyState() and GetAsyncKeyState(), both determine key state based on key up/down messages rather than the physical state of the key.

I am working on a program which manipulates input, using SendInput(), to release modifier keys (alt, ctrl, etc...), send input, and then re-press the modifier keys.

The problem is that I don't know if the modifier keys are still pressed after the input is sent because I have sent the key-up event and both of the above mentioned functions return that the key is up regardless of the state of the physical key. So if I assume they are still down, the user is left with a dangling ctrl-down causing problems until the user presses and releases cntl again (or any modifier key). Otherwise the key may be left up even when the physical key is still down.

So is there any way (preferably without anything too low level) to detect the physical key state. Windows-only methods are fine. Key monitoring (listening for key up events) really isn't possible (or at least really, really not preferable).

3条回答
等我变得足够好
2楼-- · 2020-06-29 23:46

You are getting a bit confused here. In fact GetAsyncKeyState() does return the key state at the instant that GetAsyncKeyState() was called. On the other hand, GetKeyState() returns the key state based on the history of queued messages.

查看更多
甜甜的少女心
3楼-- · 2020-06-29 23:59

You aren't giving the window manager enough time to process the input you just injected. Until it reaches the "update key states for GetAsyncKeyState" part of the code, GetAsyncKeyState will report the old value. (In particular, it won't reach that point until all low-level keyboard hooks have had a chance to inspect the action and possibly reject it.)

In other words, your code has a race condition, and that is what you are observing.

查看更多
Summer. ? 凉城
4楼-- · 2020-06-30 00:11

After much testing, I seem to have figured it out. MSDN states about GetKeyState() :

The key status returned from this function changes as a thread reads key messages from its message queue.

GetAsyncKeyState() still works on key up/down messages (not physical key state) however, it just doesn't wait for the message to be read. So if a key event message is sent via SendInput(), it will still return incorrectly - in fact, it will be incorrect before GetKeyState() because it will be incorrect immediately after the call.

A simple test to demonstrate this functionality is here (VS2010 solution) or just the source here.

查看更多
登录 后发表回答