SlideShare uma empresa Scribd logo
1 de 3
初学者导学:使用全局热键

原文: 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 Dunn 和 Colin Davies 是这么叫这些程序的。

首先要记住的一点是我们编写的热键将会对操作系统全局有效。       因此,仔细考虑一下选择什
么作为你的热键。同时判断一下你的应用程序是否重要到能够拥有操作系统级别的快捷键。
用户可能会偶然地按下 Ctrl 和 D 键[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
);


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




许可

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

翻译备注

[1] 在中国大陆,更多地称为“快捷键”
[2] cook up
[3] nice 怎么翻译
[4] 连接词不好翻译啊
[5] pop up
[6] 声明对否?
[7] 也就是 ID
[8] modifier keys:查看 google 网络释义
[9] trap
[10] what does this do
[11] somewhere 怎么解释
[12] straight API program,通俗地将,也就是 Win32 程序
[13] 难翻译
[14] kindly 如何翻译
[15] entry
[16] 感觉没表达出意思,很有疑问。
[17] 这里很意译


              原文:         Beginner's Tutorial - Using global hotkeys
             Posted:      29 Apr 2002     Author:   Nishant Sivakumar
            Translated:   July 17, 2009   Author:      ToughWater

Mais conteúdo relacionado

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

掌星 移动互联网开发笔记-Vol002
掌星 移动互联网开发笔记-Vol002掌星 移动互联网开发笔记-Vol002
掌星 移动互联网开发笔记-Vol002rainx1982
 
CICD Workshop 20180922
CICD Workshop 20180922CICD Workshop 20180922
CICD Workshop 20180922Earou Huang
 
做卓有成效的程序员
做卓有成效的程序员做卓有成效的程序员
做卓有成效的程序员Lv Jian
 
Ops as Code using Serverless
Ops as Code using Serverless Ops as Code using Serverless
Ops as Code using Serverless Rick Hwang
 
iOS 入門教學
iOS 入門教學iOS 入門教學
iOS 入門教學Steven Shen
 
OpenWebSchool - 03 - PHP Part II
OpenWebSchool - 03 - PHP Part IIOpenWebSchool - 03 - PHP Part II
OpenWebSchool - 03 - PHP Part IIHung-yu Lin
 
Cognos8.3安装配置For Db2
Cognos8.3安装配置For Db2Cognos8.3安装配置For Db2
Cognos8.3安装配置For Db2Franky Lao
 
Flex20100906
Flex20100906Flex20100906
Flex20100906reasonpun
 
第1讲 开始编写程序
第1讲 开始编写程序第1讲 开始编写程序
第1讲 开始编写程序ruandao
 
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境Will Huang
 
rebar erlang 2
rebar erlang 2rebar erlang 2
rebar erlang 2致远 郑
 
以HTML5和COIMOTION打造跨平台App
以HTML5和COIMOTION打造跨平台App以HTML5和COIMOTION打造跨平台App
以HTML5和COIMOTION打造跨平台AppBen Lue
 
API Token 入門
API Token 入門API Token 入門
API Token 入門Andrew Wu
 
SRE CH12 - Effective Troubleshooting
SRE CH12 - Effective TroubleshootingSRE CH12 - Effective Troubleshooting
SRE CH12 - Effective TroubleshootingRick Hwang
 
这年头,你只需要懂Node webkit
这年头,你只需要懂Node webkit这年头,你只需要懂Node webkit
这年头,你只需要懂Node webkitLainZQ
 
資訊安全筆記 2023_0129_0205.docx
資訊安全筆記 2023_0129_0205.docx資訊安全筆記 2023_0129_0205.docx
資訊安全筆記 2023_0129_0205.docxssuser9026c8
 
twMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC
 

Semelhante a 初学者导学:使用全局热键 (20)

GCP 的應用
GCP 的應用GCP 的應用
GCP 的應用
 
掌星 移动互联网开发笔记-Vol002
掌星 移动互联网开发笔记-Vol002掌星 移动互联网开发笔记-Vol002
掌星 移动互联网开发笔记-Vol002
 
Cocoa on Rails 4th
Cocoa on Rails 4thCocoa on Rails 4th
Cocoa on Rails 4th
 
CICD Workshop 20180922
CICD Workshop 20180922CICD Workshop 20180922
CICD Workshop 20180922
 
做卓有成效的程序员
做卓有成效的程序员做卓有成效的程序员
做卓有成效的程序员
 
Ops as Code using Serverless
Ops as Code using Serverless Ops as Code using Serverless
Ops as Code using Serverless
 
iOS 入門教學
iOS 入門教學iOS 入門教學
iOS 入門教學
 
N bear
N bearN bear
N bear
 
OpenWebSchool - 03 - PHP Part II
OpenWebSchool - 03 - PHP Part IIOpenWebSchool - 03 - PHP Part II
OpenWebSchool - 03 - PHP Part II
 
Cognos8.3安装配置For Db2
Cognos8.3安装配置For Db2Cognos8.3安装配置For Db2
Cognos8.3安装配置For Db2
 
Flex20100906
Flex20100906Flex20100906
Flex20100906
 
第1讲 开始编写程序
第1讲 开始编写程序第1讲 开始编写程序
第1讲 开始编写程序
 
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
 
rebar erlang 2
rebar erlang 2rebar erlang 2
rebar erlang 2
 
以HTML5和COIMOTION打造跨平台App
以HTML5和COIMOTION打造跨平台App以HTML5和COIMOTION打造跨平台App
以HTML5和COIMOTION打造跨平台App
 
API Token 入門
API Token 入門API Token 入門
API Token 入門
 
SRE CH12 - Effective Troubleshooting
SRE CH12 - Effective TroubleshootingSRE CH12 - Effective Troubleshooting
SRE CH12 - Effective Troubleshooting
 
这年头,你只需要懂Node webkit
这年头,你只需要懂Node webkit这年头,你只需要懂Node webkit
这年头,你只需要懂Node webkit
 
資訊安全筆記 2023_0129_0205.docx
資訊安全筆記 2023_0129_0205.docx資訊安全筆記 2023_0129_0205.docx
資訊安全筆記 2023_0129_0205.docx
 
twMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure Functions
 

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

  • 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 Dunn 和 Colin Davies 是这么叫这些程序的。 首先要记住的一点是我们编写的热键将会对操作系统全局有效。 因此,仔细考虑一下选择什 么作为你的热键。同时判断一下你的应用程序是否重要到能够拥有操作系统级别的快捷键。 用户可能会偶然地按下 Ctrl 和 D 键[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 ); 一个正规的应用程序可以使用在 0x0000 和 0xBFFF 之间的任何值作为 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]?好问题!我们已经实现的是,
  • 2. 无论何时这个热键被按下,一个 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,这个样例程序是很快被拼凑起来的,它让你选择一个单独的修饰键(它不允许多元修
  • 3. 饰符),而且你可以在 A 和 Z 之间选择一个虚拟键。还有,你可以浏览并且选择[17]一个可 执行程序,当你点击【开始】按钮以后, (刚刚浏览到的程序的)热键就启用了。这是一个 非常简单的程序,并没有真正做什么事情。但是如果我的讲解对你并不够连贯,你可以浏览 整个源代码。 许可 这篇文章,和任何相关的源代码和文件一道,都是在The Microsoft Public License (Ms-PL)许 可下的。 翻译备注 [1] 在中国大陆,更多地称为“快捷键” [2] cook up [3] nice 怎么翻译 [4] 连接词不好翻译啊 [5] pop up [6] 声明对否? [7] 也就是 ID [8] modifier keys:查看 google 网络释义 [9] trap [10] what does this do [11] somewhere 怎么解释 [12] straight API program,通俗地将,也就是 Win32 程序 [13] 难翻译 [14] kindly 如何翻译 [15] entry [16] 感觉没表达出意思,很有疑问。 [17] 这里很意译 原文: Beginner's Tutorial - Using global hotkeys Posted: 29 Apr 2002 Author: Nishant Sivakumar Translated: July 17, 2009 Author: ToughWater