`
clzqwdy
  • 浏览: 3014 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

初学者导学:使用全局热键

阅读更多

原文: Beginner's Tutorial - Using global hotkeys

Posted: 29 Apr 2002 | Author: Nishant Sivakumar

Translated: July 17, 2009 | Author: ToughWater

Version: V0.1       July 17, 2009

前言

今天早晨,有人在VC++论坛询问如何使用热键[1]。我从没使用过热键,所以它激发了我很大的兴趣。我想我将会编写[2]一个简单的应用程序,并且为CodeProject写一篇小巧[3]的文章。这些天我已经写了太多的.NET的文章,所以我想是时候写一些正规的非托管程序了,Mike DunnColin Davies是这么叫这些程序的。

 

首先要记住的一点是我们编写的热键将会对操作系统全局有效。因此,仔细考虑一下选择什么作为你的热键。同时判断一下你的应用程序是否重要到能够拥有操作系统级别的快捷键。用户可能会偶然地按下CtrlD[4],突然发现你的应用程序弹了出来[5]。事实上,如果这是个年龄足够大的用户,突然弹出的没有预料到的窗口可能会导致他或她心脏病发作。很明显,这样一种情形是要被避免的。

如何设置热键

好了,设置热键仅仅是一种API调用,而不是像有的人想的那样认为它是一个复杂的过程。我们使用RegisterHotKey这种API调用,它的原型声明[6]如下:

 

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
);

 

一个正规的应用程序可以使用在0x00000xBFFF之间的任何值作为ID值,但是如果你写的是一个DLL,那么你必须使用GlobalAddAtom方法为你的热键得到一个独特的标示符[7]。目前有四个被允许的关键修饰语 [8],也就是你可以用 Ctrl键、Alt键、Shift键和WinKey来修饰其他键。你可以单独用它们来修饰[9],或者用它们每一个的组合。例如,你可以设置这样一个组合快捷键,像Ctrl+Shift+WinKey+Y来弹出yahoo messenger,尽管你为什么想要建立那种费解的快捷键将会是一个很难回答的问题。

 

RegisterHotKey(hWndA, 100, MOD_ALT | MOD_SHIFT, 'P');
RegisterHotKey(hWndA, 200, MOD_WIN, 'R');

 

好了,设置热键就是这么简单。那么,这会有什么作用呢[10]?好问题!我们已经实现的是,无论何时这个热键被按下,一个WM_HOTKEY消息将会被发送到通过HWND参数来区分的指定窗口。Neat。同样记得如果你试图设置一个已经被注册的热键,像WinKey+E热键就会启动资源管理器Explorer,那么此时RegisterHotKey这个函数就会失败并且返回FALSE,否则它将会返回TRUE。所以请不要不检查返回值。

注销热键

正如你们所期待的,有一个API调用叫做UnregisterHotKey,这个函数可以注销我们的热键。记得当你的程序退出时注销所有的热键。事实上,注销一个可能已经被注销的热键仅仅是为了安全。那样做一点也没有害处。这个函数的原型如下:

 

BOOL UnregisterHotKey(
    HWND hWnd,  // window associated with hot key
    int id      // identifier of hot key
);

 

ID标示符是和我们已经传给RegisterHotKey的一样的。如果你已经用了GlobalAddAtom方法来得到一个独特的标示符,你必须在某个地方[11]保存它以便你可以用它来注销热键。

 

UnregisterHotKey(hWndMain,300);

处理热键

如果你正在写一个直接调用API的程序[12],你应该不会在处理WM_HOTKEY消息时有太多的困难。只要检查下wParam参数,它将会包含热键的标示符。使用MFC的问题是,由于一些奇怪的原因,类向导似乎并不包括WM_HOTKEY消息。当我最初开始写程序的时候,我使用的是VC++ 6.0 with SP5。我并不清楚VC++ 7.0是否有同样的问题,甚至不知道对于VC++ 6.0是否有处理同种难解问题的可行方案 [13]。如果你知道一种可行方案,也请让我知道[14]。但是这并不能阻止我们增加这个条目[15]到消息映射上。在规则下那样做是完美无暇的,我说[16]

 

ON_MESSAGE(WM_HOTKEY,OnHotKey)

 

好了,上面那个非常简单。现在,我们增加我们的(处理)函数。仅仅增加这个函数到你的窗口类,就是那个将要接收WM_HOTKEY消息的窗口所在的类。

 

LRESULT OnHotKey(WPARAM wParam, LPARAM lParam);

 

现在你所有要做的事情就是写函数体,检查wParam参数,然后看一下它是否是你的热键的ID,接着做你想做的。非常典型地,你可能会想用ShellExecute来开启你的程序,这个我已经在这篇文章的样例程序中做了。

样例程序

Well,这个样例程序是很快被拼凑起来的,它让你选择一个单独的修饰键(它不允许多元修饰符),而且你可以在AZ之间选择一个虚拟键。还有,你可以浏览并且选择[17]一个可执行程序,当你点击【开始】按钮以后,(刚刚浏览到的程序的)热键就启用了。这是一个非常简单的程序,并没有真正做什么事情。但是如果我的讲解对你并不够连贯,你可以浏览整个源代码。

样例程序

许可

这篇文章,和任何相关的源代码和文件一道,都是在The Microsoft Public License (Ms-PL)许可下的。

 

 

点击下面的链接下载:

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics