文章目录
- [1 按回车键 程序闪退问题](#1 按回车键 程序闪退问题)
-
- [1.1 问题描述](#1.1 问题描述)
- [1.2 原因分析](#1.2 原因分析)
- [1.3 解决办法](#1.3 解决办法)
-
- [1.3.1 方法一:OnOK函数写成空函数](#1.3.1 方法一:OnOK函数写成空函数)
- [1.3.2 方法二: 直接返回](#1.3.2 方法二: 直接返回)
- [2 关闭 ESC键程序退出 问题](#2 关闭 ESC键程序退出 问题)
-
- [2.1 [方法1]](#2.1 [方法1])
- [2.2 [方法2]](#2.2 [方法2])
1 按回车键 程序闪退问题
1.1 问题描述
在输入框输入完毕后一般习惯 回车键,
但MFC程序运行后,在编辑框输入回车,运行窗口立即退出。
在一般情况下编写的对话框程序,用户在运行的时候,如果不注意按下了ENTER或者 ESC键,程序就会立刻退出,
1.2 原因分析
产生这样的原因,有以下几种情况:
-
①按下Enter 键时,Windows 就会自动去找输入焦点落在了哪一个按钮上,当获得焦点的按钮的四周将被点线矩形包围。
-
②如果所有按钮都没有获得输入焦点,windows 就会自动去寻找程序或资源所指定的默认按钮(默认按钮边框较粗)。
-
③如果对话框没有默认按钮,那么即使对话框中没有 OK 按钮,OnOK 函数也会动被调用,
对于一个普通的对话框程序来说,OnOK 函数的调用,以为着程序会立刻退出。
1.3 解决办法
1.3.1 方法一:OnOK函数写成空函数
为了使Enter 键无效,最简单的办法就是将 CExDIg的OnOK函数写成空函数
,然后针对OK按钮写一个新的函数来响应。
(事实上针对OK按钮,我没有写一个新的函数,但系统自带的 确认/取消 按钮仍然可用)
在...Dlg.h文件中申明
cpp
void OnOK();
在...Dlg.cpp文件中写一个空的OnOK()函数
cpp
void CSerialPortDlg::OnOK()
{
//MFC的Enter键默认调用OnOK 函数,
//用户在运行的时候,如果不注意按下了ENTER或者 ESC键,程序就会立刻退出,
//为了使Enter 键无效,最简单的办法就是将的OnOK函数写成空函数
//此时,系统自带的 确认/取消 按钮仍然可用
}


到此解决了
1.3.2 方法二: 直接返回
自己的操作完成之后一定要直接返回,不要把回车消息继续交给MFC函数处理!!!
cpp
BOOL CSSmallClassDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if (pMsg->message == WM_KEYDOWN)
{
//是回车消息 并且 是你的编辑框上的 回车消息
if (pMsg->wParam == VK_RETURN && pMsg->hwnd == m_SendDataEdit.m_hWnd)
{
//中间 你自己 的 响应操作
//自己添加的 代码 完成后 就直接返回 不要把消息继续交给下边的函数(系统处理)
return TRUE;
}
}
return __super::PreTranslateMessage(pMsg);
}
2 关闭 ESC键程序退出 问题
ESC键的原理也是如此,它是默认和 OnCancel函数映射在一起的。对于 ESC 键,需要自己重载 CDialog 类的 PreTranslateMessage 函数,当发现是 ESC 键的时候,过滤掉这个消息或者是替换掉这个消息。
以下是简单的代码示例
2.1 [方法1]
可以先重载OnOK函数
cpp
void CTestDlg::OnOK()
{
//里面什么也不写
}
然后重载 PreTranslateMessage 函数,把 ESC 键的消息,用RETURN 键的消息替换,这样,按 ESC的时候,也会执行刚才的OnOK 函数,这样问题就可以解决了
cpp
BOOL CxxxDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
{
pMsg->wParam = VK_RETURN;//将ESC键的消息替换为回车键的消息,这样按ESC的时候//也会去调用 OnOK函数,而OnOK什么也不做,这样ESC也被屏蔽
}
return CDialog::PreTranslateMessage(pMsg);
}
2.2 [方法2]
直接在重载的 PreTranslateMessage函数中屏蔽回车和 ESC的消息,和以上方法大同小异
cpp
BOOL CxxxDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
return TRUE;
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
return TRUE;
else
return CDialog::PreTranslateMessage(pMsg);
}