如何防止RegisterHotKey停止默认按键操作?

3
我正在使用Windows API的RegisterHotKey函数,在特定应用程序打开并聚焦时按下F2键运行宏。但是,这将阻止其他应用程序(如Excel)使用F2键。如何防止RegisterHotKey停止默认操作?我有一个系统托盘应用程序,使用this answerHotKeyManager类来注册热键。当按下特定键(例如F2)时,我使用Windows API检查是否打开且聚焦了一个闭源应用程序,如果是,则发送一系列SendKeys

如果您只关心特定的应用程序,则RegisterHotKey()不是正确的方法。相反,使用SetWindowsHookEx()来设置低级键盘钩子,GetForegroundWindow + GetWindowThreadProcessId来查找拥有前台窗口的进程。 - Hans Passant
Hans,你应该把那个变成一个答案。我认为这是正确的做法。 - Andy Davis
1
据我所知 - 您希望全局热键仅在一个或多个选定的应用程序处于焦点时起作用。如果确定不兼容的应用程序在前台,您不能简单地发送拦截的按键吗?您这样做了吗? - Ani
@ananthonline 我没想到尝试那个。我会试一下并告诉你它是否有效,虽然我仍然有兴趣尝试 SetWindowsHookEx() :) - Rachel
@ananthonline 在我的情况下,那实际上非常有效。我仍然计划在有更多时间时调查 SetWindowsHookEx,但现在你的解决方案非常好用。你应该将它发布为答案 :) - Rachel
2个回答

2

RegisterHotKey是全局的,所以它将捕获所有这些按键(换句话说,我不认为可以完全按照您的要求进行操作)。

然而,这个线程 Global Keyboard Hooks (C#) 讨论了创建键盘消息过滤器,这更像是您想要的。

澄清一下: 对于托盘应用程序和任何其他需要不依赖于应用程序焦点的OS范围键盘快捷方式的地方,RegisterHotKey是最好的选择。

Application.AddMessageFilter()是您希望在应用程序已经具有焦点时仅处理特定按键的一致处理的方法。

一种在仍然停留在.NET中实现您所描述的内容并仍然监视操作系统上正在运行的进程,并仅在您的应用程序运行时启用全局钩子的方法。


@Rachel,你有访问运行RegisterHotKey的应用程序代码的权限吗?那个应该设置键盘钩子。从你的评论中我不清楚你是缺少那个代码还是缺少问题第一句话中的“特定应用程序”的代码。如果是后者,你仍然不需要修改那个“特定应用程序”。 - user743382
@hvd 我可以访问托盘应用程序,其中运行了“RegisterHotKey”。我认为我可能误解了您提供的链接中发布的代码 :) - Rachel
@Rachel 对于托盘应用程序,通常需要使用RegisterHotKey,因为它不会拥有焦点。你能否更详细地说明一下你想要做什么? - Andy Davis
@hvd,我想问题在于它运行得太好了。如果另一个应用程序没有运行,那么她希望挂钩可以让按键继续到达其正常目标。 - Andy Davis
@Rachel 这不应该是个问题。如果你以前没有使用过钩子,我的建议是选择一个全局键盘钩子示例应用程序,验证它是否有效,然后逐步删除不需要的部分,检查每个步骤后它是否仍然有效。剩下的就是你应该包含在自己的程序中的内容。钩子可能会导致痛苦的调试体验,因此从已知可行的代码开始可以使它变得更容易。当然,如果你有具体的问题,请随时提问(甚至可以在SO上作为新问题)。 - user743382
显示剩余5条评论

2

据我理解,您希望全局热键仅在某一个或多个选定的应用程序被聚焦时有效。如果确定不兼容的应用程序在前台,那么您是否可以简单地使用SendKeys发送拦截到的按键?

例如:

if (IsSpecificWindowFocused())
{
    // Do work
}
else
{
    // Resend the key to whatever window is current
    SendKeys.Send("{F2}");
}

谢谢,这对我的情况很有效。我仍然计划在某个时候研究全局键盘钩子,但这是一个不错的简单解决方案,解决了我目前的问题 :) - Rachel
所以,如果你只对它的一个小子集感兴趣,为什么要一直捕获它呢?根据其他答案的说法,如果你想要一个特定于单个应用程序的版本,请创建一个特定于单个应用程序的版本。 - Deanna
@Deanna 根据我的理解,OP的问题是“我使用Windows API来检查一个闭源应用程序是否处于打开和聚焦状态,如果是,则发送一系列的SendKeys” - 需要发送“宏”的应用程序无法更改。在这种情况下,全局热键是唯一的选择。 - Ani
另请参阅链接答案中的评论 - https://dev59.com/SGjWa4cB1Zd3GeqPnRcp#vGMFoYgBc1ULPQZFaSun - Ani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接