一、建立一個 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