添加全局热键

Intercepting Keyboard Input

Using the Win32 API, you can create an application that listens for particular keystrokes by utilizing any one of several methods. The simplest method involves using the API RegisterHotKey. This API takes an hwnd, an ID, a virtual key, and a key modifier. If this call is successful, the hwnd's WndProc will receive a WM_HOTKEY message with the wParam of the message equal to ID whenever the virtual key and key modifier is pressed. This occurs whether the listener application window is active or not. The following call would cause hwndApp to be notified with a WM_HOTKEY message whenever AltTab is pressed:

RegisterHotKey(hwndApp, IDH_ALTTAB, MOD_ALT, VK_TAB)

Before Windows XP, attempting to register AltTab as a hot key would fail. As of Windows XP, not only can you successfully register AltTab as a hotkey, Windows XP will also allow you to handle this event yourself, rather than initiate its own built-in AltTab hotkey handler.

 

// Create a dummy window that listens for the hotkey
HWND hwndApp = CreateWindow(WC_APP, NULL, 00000, HWND_MESSAGE, 
               NULL, THIS_EXE, NULL);
if (hwnd)
...{
    
// register Alt+Tab 
    RegisterHotKey(hwndApp, IDH_NEXT, MOD_ALT, VK_TAB);
    RegisterHotKey(hwndApp, IDH_PREV, MOD_ALT
|MOD_SHIFT, VK_TAB);

    MSG msg;
    
while (GetMessage(&msg, NULL, 00))
    
...{
        TranslateMessage(
&msg);
        DispatchMessage(
&msg);
    }

}


LRESULT WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
...{
    
switch (uMsg)
    
...{
        
case WM_HOTKEY:
        
...{
            
switch (wParam)
            
...{
                
// if the container window is not showing, enumerate
                
// the top-level windows, extract their icon and text,
                
// and present them in a container window
                case IDH_NEXT:
                
...{
                    
// select the icon of the next top-level window
                    
// in the window hierarchy
                    break;
                }

                
case IDH_PREV:
                
...{
                    
// select the icon of the previous top-level
                    
// window in the window hierarchy
                }

            }

        }

    }

}

对于一个后台程序,常常需要添加一个热键,此时,由于此时应用程序不在桌面,所以那些标准的MFC中定义的消息以及相关处理函数也不再有用。一般的做法是:

在init中做完必要的操作后,先注册一个系统热键,程序退出后释放掉。

系统热键的注册

  根据前面的介绍,不难写出为后台服务程序添加对系统热键响应的功能代码。为了避免重复注册热键,首先通过函数GlobalFindAtom()查询本服务程序所对应的全局原子是否已存在于全局原子表中,如果发现,则说明系统中已经存在有此服务,程序退出。如果没有发现,则通过GlobalAddAtom()函数向全局原子表添加一个字串,并获取得到一个唯一标识此字串的原子。以上两函数原型分别为:

ATOM GlobalFindAtom(LPCTSTR lpString);
ATOM GlobalAddAtom(LPCTSTR lpString);

  其中,输入参数为一个描述原子的字符串,如果GlobalFindAtom()从全局原子表中找到了指定的字串,那么将返回此字串对应的原子,否则返回0。GlobalAddAtom()如果创建成功,将返回一个新创建的原子。
接下来,为了能在程序运行期间捕获到系统热键,需要通过RegisterHotKey()定义一个系统范围的热键。该函数原形如下:

BOOL RegisterHotKey(HWND hWnd, // 接收热键响应的窗口句柄
int id, // 热键的标识
UINT fsModifiers, // 控制键标志
UINT vk // 虚拟键值
);

  其中,热键标识id必须是一个范围在0xC000到0xFFFF之间的全局唯一的值,为了避免可能引起的热键冲突,通常把GlobalAddAtom()返回的原子作为参数传入,而且GlobalAddAtom()返回值的范围同id参数的允许范围是完全一致的。参数fsModifiers定义了同虚拟键值vk同时按下而产生出系统热键消息WM_HOTKEY的控制键组合,如MOD_ALT、MOD_CONTROL、MOD_SHIFT和MOD_WIN等。在本例中将要设定的系统热键为Alt+Ctrl+R,因此,参数fsModifiers和vk分别设置为MOD_ALT| MOD_CONTROL和VK_R。有关系统热键的注册实现方法可以整理如下:

// 获取当前窗口句柄
HWND handle = GetSafeHwnd();
// 寻找HotKey对应的原子是否存在于原子列表
if(GlobalFindAtom("Hotkey") == 0)
{
// 如果没有存在于原子列表,则创建一个原子
id = GlobalAddAtom("Hotkey");
//注册全局热键Ctrl + Alt + R
RegisterHotKey(handle, id, CONTROL + ALT, R);
}
else // 如果HotKey已经存在于原子列表,则终止程序运行
PostQuitMessage(0);
 
阅读更多
个人分类: File/System
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭