文章目录
- 问题描述
- 问题原因
- 解决办法
- 方法一:在重载的PreTranslateMessage 函数中屏蔽回车和ESC 的消息
- 方法二:重载OnOK函数
- 方法三:将所有按钮类型设为普通按钮,并设置其中一个按钮为默认按钮
问题描述
一般情况下编写的MFC对话框程序在运行的时候,如果不注意按下了ENTER 或者Esc 键,程序窗口就会默认退出。
问题原因
之所以会这样,是因为按下 Enter 键时,Windows 就会自动去找输入焦点落在了哪一个按钮上,但获得焦点的按钮的四周将被点线矩形包围。如果所有按钮都没有获得输入焦点,Windows 就会自动去寻找程序或资源所指定的默认按钮(默认按钮边框较粗)。 如果对话框没有默认按钮,那么即使对话框中没有OK 按钮,OnOK 函数也会自动被调用,对于一个普通的对话框程序来说,OnOK 函数的调用, 以为着程序会立刻退出。
为了使Enter 键/Enter 键无效,可将CExDlg 的OnOK 函数写成空函数, 然后针对OK 按钮写一个新的函数来响应。Esc 键的原理也类似,它是默认和OnCancel 函数映射在一 起的。对于 ESC 键/Enter 键,也可重载 CDialog 类的PreTranslateMessage 函数,当发现是 ESC 键/Enter 键的时 候,过滤掉这个消息或者是替换掉这个消息。
解决办法
方法一:在重载的PreTranslateMessage 函数中屏蔽回车和ESC 的消息
BOOL CxxxDlg::PreTranslateMessage(MSG* pMsg)
{
//屏蔽ESC键按下
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
{
return TRUE;
}
//屏蔽Enter键按下
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN && pMsg->wParam)
{
return TRUE;
}
//操作其他msg
return CDialog::PreTranslateMessage(pMsg);
}
方法二:重载OnOK函数
void CxxxDlg::OnOK()
{
// TODO: Add extra validation here
return;
}
void CxxxDlg::OnClickedOk()
{
// TODO: Add your control notification handler code here
CDialog::OnOK();
}
方法三:将所有按钮类型设为普通按钮,并设置其中一个按钮为默认按钮
这样下次按Enter 键就默认执行默认按钮的功能(比如刷新)。
注意:尽量让所有按钮类型设为普通按钮(按钮ID 为IDC_BUTTON* 这种),否则如果存在按钮ID为IDC_CANCEL*(常用取消类型按钮)等其他类型按钮,则按Enter 键程序窗口还是会关闭!只需将关闭等按钮类型也变为IDC_BUTTON*的普通按钮类型即可(也可直接复制一个普通按钮去代替做取消功能,替换原取消按钮)。