初学者教程——使用全局热键






4.91/5 (44投票s)
讲解如何注册、使用和注销热键

引言
今天早上,有人在 VC++ 论坛上问及如何使用热键。我以前从未用过热键,这引起了我很大的兴趣。我想,我应该创建一个简单的应用程序,并为 CP 写一篇不错的短文。最近我写了太多 .NET 的文章,我认为是时候写一篇普通的非托管程序了,就像 Mike Dunn 或 Colin Davies 会称呼的那样。
首先,请记住热键将是全局的,对整个操作系统都有效。因此,请谨慎选择你的热键。同时也要决定你的应用程序是否足够重要,以至于需要一个操作系统级别的快捷键。用户可能会意外地按下 Ctrl-D,然后突然发现你的程序弹出。事实上,如果用户年纪较大,突然弹出一个意想不到的窗口可能会让他或她心脏病发作。这显然是一种需要避免的情况。
如何设置热键
好吧,对于任何认为这是一个复杂过程的人来说,设置热键只需一个 API 调用即可。我们使用 API 调用 RegisterHotKey
,其原型如下。
BOOL RegisterHotKey( HWND hWnd, // window to receive hot-key notification int id, // identifier of hot key UINT fsModifiers, // key-modifier flags UINT vk // virtual-key code );
普通应用程序可以使用 0x0000 到 0xBFFF 之间的任何值,但如果你正在编写一个 DLL,则必须使用 GlobalAddAtom
来获取热键的唯一标识符。目前有四种允许的键修饰符,可以让你捕获 Ctrl
键、Alt
键、Shift
键和 WinKey
。你可以单独或组合使用它们。例如,你可以有一个组合快捷键,如 Ctrl-Shift-WinKey-Y 来弹出雅虎通,尽管为什么你要设置这种迂回的快捷键将是一个很难回答的问题。
RegisterHotKey(hWndA, 100, MOD_ALT | MOD_SHIFT, 'P'); RegisterHotKey(hWndA, 200, MOD_WIN, 'R');
好的,设置热键很简单。那么,这有什么作用呢?好问题!我们已经实现的是,每当按下该热键时,都会向由 HWND
参数指定的窗口发送一个 WM_HOTKEY
消息。很方便。另外请记住,如果你尝试设置一个已经被注册的热键,例如会弹出 Explorer 的 WinKey-E 热键,此函数将失败并返回 FALSE
,否则将返回 TRUE
。所以,请务必检查返回值。
注销热键
好吧,正如你所料,有一个名为 UnregisterHotKey
的 API 调用,它可以注销我们的热键。请记住,在程序退出时注销所有热键。事实上,为了安全起见,可以尝试注销一个可能已经被注销过的按键。完全不会造成任何损害。此函数原型如下:
BOOL UnregisterHotKey( HWND hWnd, // window associated with hot key int id // identifier of hot key );
标识符与我们传递给 RegisterHotKey
的标识符相同。如果你使用 GlobalAddAtom
获取唯一标识符,你必须将其保存在某处,以便可以使用它来注销热键。
UnregisterHotKey(hWndMain,300);
处理热键
如果你正在编写一个纯 API 程序,处理 WM_HOTKEY
消息应该不会太困难。只需检查 wParam
,它将包含热键的标识符。MFC 的问题在于,不知何故,类向导似乎不包含 WM_HOTKEY
消息。我最初编写程序时使用的是 SP5 的 VC++ 6.0。我不知道 VC++ 7.0 是否也如此,或者 VC++ 6.0 是否有某种晦涩的解决方法。如果有人知道解决方法,也请告诉我。但没有什么可以阻止我们向消息映射添加条目。我说,这样做完全符合规则。
ON_MESSAGE(WM_HOTKEY,OnHotKey)
好吧,这很简单。现在我们添加函数。只需将此函数添加到你的窗口类中,该窗口将接收 WM_HOTKEY
消息。
LRESULT OnHotKey(WPARAM wParam, LPARAM lParam);
现在你所要做的就是编写函数体,检查 wParam
,看看它是否是你的热键标识符,然后执行你想要的操作。通常,你可能想使用 ShellExecute
来启动你的程序,这也是我在本文示例程序中所做的。
示例程序
好吧。示例程序很快就完成了,它可以让你选择一个单独的修饰键(不允许多个修饰键),并且你可以选择 A 到 Z 之间的虚拟键。你还可以浏览到可执行文件,当你单击“开始”按钮时,热键就生效了。这是一个非常简单的程序,实际上并没有做什么。但你可以查看源代码,如果我的解释不够清晰。