1. 程式人生 > >VC中的RegisterHotKey函式與HotKey控制元件(CHotKeyCtrl)

VC中的RegisterHotKey函式與HotKey控制元件(CHotKeyCtrl)

1、其實,關於RegisterHotKey函式本人寫過一個簡單的示例,主要是利用這個函式實現全域性熱鍵。

2、本文記錄的重點是通過Hot Key控制元件設定的熱鍵,如何正確的用RegisterHotKey函式註冊。

3、思路很清晰,將使用者在控制元件的輸入通過函式GetHotKey獲得,獲取到的值包括兩個,一個是熱鍵的組合型別,譬如Ctrl + X、Shift + X、ALT + X或者Ctrl + Shift + X,而另一個就是X。

4、但是,我們發現直接將GetHotKey獲取到的值代入RegisterHotKey函式執行,有時會出問題。當然,這裡所謂的問題不是編譯的問題,而是當你註冊了一個熱鍵,卻發現一直不進熱鍵的訊息函式。

5、具體的情況是:

(1)形如Ctrl + X的熱鍵一切正常;

(2)形如Shift + X和Alt + X的熱鍵不響應;

... ...

6、如果細心的朋友會發現,當你在控制元件中設定熱鍵為Shift + X並直接呼叫函式RegisterHotKey時,其實註冊的結果是Alt + X。也就是說,Shift和Alt這兩個值搞反了。

7、那麼,是不是一個Bug呢?我們不放仔細看一下兩者的定義:

(1)RegisterHotkey函式第三個引數的說明:

fsModifiers [in] Specifies keys that must be pressed in combination with the key specified by thenVirtKey
parameter in order to generate a WM_HOTKEY message. The fsModifiers parameter can be a combination of the following values.
Value Description
MOD_ALT Either ALT key must be held down.
MOD_CONTROL Either CTRL key must be held down.
MOD_KEYUP Both key up events and key down events generate a WM_HOTKEY message.
MOD_SHIFT Either SHIFT key must be held down.
MOD_WIN Either WINDOWS key was held down. These keys are labeled with the Microsoft Windows logo.
(2)在看一下GetHotKey第二個引數的說明:

Call this function to retrieve the virtual key code and modifier flags of a hot key from a hot key control.

DWORD GetHotKey( ) const;
void GetHotKey(
   WORD &,
   WORD & 
) const;

Parameters

wVirtualKeyCode
Virtual key code of the hot key. For a list of standard virtual key codes, see Winuser.h.
wModifiers
Modifier flags indicating the keys that, when used in combination with wVirtualKeyCode, define a hot key combination.

Return Value

In the first usage above, a DWORD containing the virtual key code and modifier flags. The low-order word is the virtual key code, and the high-order word is the modifier flags. The HIWORD and LOWORD of this 32-bit value can be used as the parameters in the SetHotKey member function.

Remarks

The modifier flags can be a combination of the following values:

  • HOTKEYF_ALT   ALT key
  • HOTKEYF_CONTROL   CTRL key
  • HOTKEYF_EXT   Extended key
  • HOTKEYF_SHIFT   SHIFT key 

8、注意我標紅的地方,下面我們看一下定義:

(1)Microsoft SDKs\Windows\v7.0A\Include\WinUser.h

#define MOD_ALT         0x0001 #define MOD_CONTROL     0x0002 #define MOD_SHIFT       0x0004

(2)Microsoft SDKs\Windows\v7.0A\Include\CommCtrl.h

#define HOTKEYF_SHIFT           0x01 #define HOTKEYF_CONTROL         0x02 #define HOTKEYF_ALT             0x04

9、這下問題清楚了,提供兩個轉換函式:

UINT ModToHotkey(UINT fsModifiers) { if ( (fsModifiers & MOD_SHIFT) && !(fsModifiers & MOD_ALT) ) // shift轉alt { fsModifiers &= ~MOD_SHIFT; fsModifiers |= HOTKEYF_SHIFT; } else if ( !(fsModifiers & MOD_SHIFT) && (fsModifiers & MOD_ALT) ) // alt轉shift { fsModifiers &= ~MOD_ALT; fsModifiers |= HOTKEYF_ALT; } return fsModifiers; } UINT HotkeyToMod(UINT fsModifiers) { if ( (fsModifiers & HOTKEYF_SHIFT) && !(fsModifiers & HOTKEYF_ALT) ) // shift轉alt { fsModifiers &= ~HOTKEYF_SHIFT; fsModifiers |= MOD_SHIFT; } else if ( !(fsModifiers & HOTKEYF_SHIFT) && (fsModifiers & HOTKEYF_ALT) ) // alt轉shift { fsModifiers &= ~HOTKEYF_ALT; fsModifiers |= MOD_ALT; } return fsModifiers; }