一、熱鍵注冊
步驟一:聲明一個全局量int hotkeyId=1:
步驟二:窗體創建的時候注冊:
int result= RegisterHotKey(this->GetHWND(), hotkeyId, MOD_ALT, 'C');
步驟三:熱鍵消息處理(窗體消息處理函數中)
if (uMsg == WM_HOTKEY)
{
if (hotkeyId == wParam)
{
DoClip();
return 0;
}
}
步驟三:窗體關閉,熱鍵注銷
int result= UnregisterHotKey(this->GetHWND(), hotkeyId);
二、組合鍵
例子:消息處理函數中
else if (wParam == 'C')
{
if (::GetKeyState(VK_SHIFT)<0)
{
DoClip();
} // < 0被按下
}
vc視圖類程序可以接收OnKeyDown消息,但在對話框上卻需要PreTranslateMessage處理按鍵消息,
而且系統按鍵Alt,F10也需要特殊處理。
還是直接上代碼:
BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
CString str;
CString strMsg;
int valid_down=0;
static int SHIFT=0;
int CAPITAL=0;
static int CTRL=0;
static int ALT=0;
static int F10=0;
short key_down=0;
short alt_down=0;
short f10_down=0;
short ctrl_down=0;
//通過檢測消息知道,這些鍵的按鍵狀態如下:
//第1次按下為 0xFFFFFF81 ,彈起卻為 1
//第2次按下為 0xFFFFFF80 ,彈起卻為 0
//以后重復上述邏輯過程
//所以,最低位0x0f不容易判定,要判定高位才可
key_down = GetKeyState(VK_MENU) & 0xff00;//81 80
if (key_down) ALT=1;
else ALT=0;
key_down = GetKeyState(VK_SHIFT)& 0xff00;//81 80
if (key_down) SHIFT=1;
else SHIFT=0;
key_down = GetKeyState(VK_CONTROL)& 0xff00;//81 80
if (key_down) CTRL=1;
else CTRL=0;
//F10 2次點擊
key_down = GetKeyState(VK_F10) & 0xff00;//81 80
if (key_down) F10=1;
else F10=0;
str.Format("%0x,m=%d,w=%d,l=%ld",key_down,pMsg->message,pMsg->wParam,pMsg->lParam);//pMsg->wParam);
SetWindowText(str);
//因為在按下Alt鍵后,再按其它鍵,就沒有KEYDOWN消息,仍然是WM_SYSKEYDOWN,只不過 pMsg->wParam是按鍵的碼制
//為了簡單,這里記住ALT F10等系統鍵的按下后,如果仍然有其它按鍵,則通過pMsg->wParam來判別
//沒有系統按鍵,就檢測WM_KEYDOWN,所以三者是並行關系
if ( CTRL || ALT || SHIFT )
{
if ( pMsg->message==260 ) return TRUE;//有其它鍵按鍵按下,直接返回,等待彈起再處理
if ( CTRL )
{//Ctrl鍵按下時,不是一般鍵,或者F10鍵彈起,就直接返回
if ( (pMsg->message!=257 && pMsg->message!=261) ) return TRUE;//有其它鍵按鍵按下,直接返回,等待彈起再處理
}
}
if (pMsg->message==WM_KEYUP || CTRL || ALT || SHIFT || F10)//檢測按鍵彈起
{
// if (0x8000 & GetKeyState(VK_SHIFT) ) SHIFT=1;
// if (0x8000 & GetKeyState(VK_CONTROL) ) CTRL=1;
// if (0x0080 & GetKeyState(VK_MENU) ) ALT=1;
if (GetKeyState(VK_CAPITAL)!=0) CAPITAL=1;
//F1-F24
if (pMsg->wParam>=0x70 && pMsg->wParam<=0x87)
{
if (pMsg->wParam>=0x70 && pMsg->wParam<=0x78)//F1-F9
str.Format("F%c",pMsg->wParam-0x70+'1');
else if (pMsg->wParam>=0x79 && pMsg->wParam<=0x7B)//F10-F12
str.Format("F1%c",pMsg->wParam-0x79+'0');
else if (pMsg->wParam>=0x7C && pMsg->wParam<=0x84)//F13-F21
str.Format("F2%c",pMsg->wParam-0x7C+'3');
else if (pMsg->wParam>=0x85 && pMsg->wParam<=0x87)//F22-F24
str.Format("F2%c",pMsg->wParam-0x85+'2');
valid_down=1;
}
//A-Z
if (pMsg->wParam>='A' && pMsg->wParam<='Z')
{
if ( SHIFT || CAPITAL )
str.Format("%c",pMsg->wParam);
else
str.Format("%c",pMsg->wParam-'A'+'a');
valid_down=1;
}
//0-9
if (pMsg->wParam>='0' && pMsg->wParam<='9')
{//正常數字鍵盤
str.Format("%c",pMsg->wParam-'0'+48);
valid_down=1;
}
//0-9
if (pMsg->wParam>=0x60 && pMsg->wParam<=0x69)
{//小鍵盤上的數字鍵
str.Format("%c",pMsg->wParam-0x60+48);
valid_down=1;
}
switch(pMsg->wParam)
{
case VK_RETURN :
str="回車";
valid_down=1;
break;
case VK_BACK:
str="back";
valid_down=1;
//……
}
if (valid_down==1) //有效按鍵
{
// if (CAPITAL) str="CapsLock + "+str;
if (SHIFT ) str="Shift + "+str;
if (ALT ) str="Alt + "+str;
if (CTRL ) str="Ctrl + "+str;
GetDlgItem(IDC_BUTTON1)->SetWindowText(str);
}
}
return CDialog::PreTranslateMessage(pMsg);
}