Windows api:等到所有键盘键在系统范围内释放
Posted
技术标签:
【中文标题】Windows api:等到所有键盘键在系统范围内释放【英文标题】:Windows api: wait until all keyboard keys are released system wide 【发布时间】:2015-11-15 14:25:18 【问题描述】:我在 Delphi 中制作了一个应用程序,可以处理一些已定义的系统范围的热键,效果很好。但是,对于某些热键功能,我必须触发/模拟一些键盘敲击,例如 ALT+ENTER。这在用户直接释放热键时效果很好,但是当用户仍然按下键时,键盘模拟失败。
有没有办法(使用 Windows API)在我处理键盘模拟之前检查是否所有键都被释放?
【问题讨论】:
为什么不使用内置热键支持的动作管理器呢?或者您想在您的应用程序之外捕获这些事件?另一方面,我们需要了解您当前的代码是如何工作的,以便能够建议如何继续。 伪造输入是一件棘手的事情。通常最好避免。 感谢 cmets。这个问题与这个问题有关:***.com/questions/32062929/…。如果您知道如何管理 DirectX 窗口,则不需要任何键。在这种情况下并不棘手,因为我可以检查窗口的状态。如果未应用 ALT+ENTER,则不会发生任何事情。已经更改了代码分配。是的,热键是在应用程序之外处理的,所以操作管理器没有用。但为什么所有这些担忧?请回答我的问题,我知道我在做什么以及为什么。 问题是:是否可以使用 Windows API 检查键盘按键的状态。我已经找到了 getKeyboardState 但不知道如何使用它。找不到有用的例子。 我对***的一些人不太了解,为什么要downvote,这个问题有什么问题?请,当您投反对票时,请留下您投反对票的原因。在这种情况下,这是令人沮丧的,我无法做任何事情来改善这个问题,因为我不知道它有什么问题。无论如何,那里有赞成票,所以我认为有些人的发型很糟糕?我不知道。 【参考方案1】:使用GetAsyncKeyState,因为此 API 反映了键盘的真实当前状态,而不是您的应用上次调用 GetMessage
的时间。只需编写一个循环,为 0 到 0xFF 之间的每个值调用它。
如果设置了最高有效位,则键向下
【讨论】:
@DavidHeffernan:为什么不呢? 循环遍历所有键,轮询?为什么不一口气问键盘状态呢? @DavidHeffernan:当然,最好一次性捕获所有键的键盘状态,这就是GetKeyboardState
所做的。但是,状态与调用应用程序的消息循环同步,这可能不利于监控其他应用程序对键盘的使用。无论如何,需要一个循环来确定是否有任何键被关闭
你真正需要的是自动化而不是伪造输入
if(GetAsyncKeyState(x) & 0x8000) // high bit is set. Key is currently held down.
【参考方案2】:
感谢@David Ching 和@David Heffernan(两个大卫!)解决方案不仅要测试键盘输入,还要测试鼠标输入或更好的输入设备状态。
鼠标也包含在内是因为:
Virtual Keys, Standard Set
VK_LBUTTON = 1;
VK_RBUTTON = 2;
VK_MBUTTON = 4; NOT contiguous with L & RBUTTON
因此,如果不想测试鼠标按钮,则必须将其从循环中排除。最好也检查一下这些,因为有些热键必须与鼠标一起使用。最好检查输入上的所有内容是否空闲。
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;
【讨论】:
以上是关于Windows api:等到所有键盘键在系统范围内释放的主要内容,如果未能解决你的问题,请参考以下文章
使用 C#/Windows API 的虚拟键盘 - 发送键输入,但不获取焦点