一、建立一個 MFC 對話盒程式 (可直接下載這邊的範例 DlgKeystroke-0.001.zip)
二、處理 dialog 的 virtual BOOL PreTranslateMessage(MSG* pMsg)
範例1:
if (pMsg->message == WM_KEYDOWN) { if (pMsg->wParam == VK_RETURN) pMsg->wParam = VK_TAB; } else { return CDialog::PreTranslateMessage(pMsg); }
這樣處理的話,在對話盒按下 Enter 會變成 Tab
範例2:
int iChanged = 0; // If this is a system message, is the Alt bit of the message on? if (pMsg->wParam == VK_MENU) { bool AltBit = false; if ((pMsg->message & WM_SYSKEYDOWN) || (pMsg->message & WM_SYSKEYUP)) { AltBit = (pMsg->lParam & (1 << 29)) != 0; if (bAlt != AltBit) bAlt = AltBit; } iChanged++; } #if 0 if (pMsg->wParam == VK_CONTROL) { if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) { if (bCtl != true) bCtl = true; } else if (pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP) { if (bCtl != false) bCtl = false; } } #else if (::GetKeyState(VK_CONTROL) < 0) { if (bCtl != true) bCtl = true; } else { if (bCtl != false) bCtl = false; } #endif // This is an accelerator example. // If the user press Alt+F5, this dialog closes. // if (pMsg->wParam == VK_F5 && pMsg->message == WM_SYSKEYUP) { iChanged++; if (bAlt) PostMessage(WM_CLOSE); } return (iChanged != 0) ? TRUE : CDialog::PreTranslateMessage(pMsg);
其中的 bAlt 和 bCtl 為整體變數如下:
bool bAlt = false; bool bCtl = false;
Alt 鍵在 VC 裡被定義為 VK_MENU,而且按下了 Alt 的話,pMsg->message 得到的是 WM_SYSKEYDOWN,並非常見的 WM_KEYDOWN
Ctrl 就跟正常的鍵一樣 pMsg->message 是 WM_KEYDOWN、WM_KEYUP;pMsg->wParam 為 VK_CONTROL
或者也可以使用 if (::GetKeyState(VK_CONTROL) < 0) 來檢查 Ctrl 鍵是否按下去
最後有個簡單的範例,表現出按下 Alt+F5 的話,對話盒就會結束……而系統內建的 Alt+F4 結束當然也還在
(也可直接下載範例 DlgKeystroke-0.002.zip)
ref:
• Keyboard messages/accelerators handling in MFC dialog based applications
• Handling accelerator in a dialog
#mfc #c++ #programming