ESC键直接退出MFC对话框问题解决?

本文提供了一种解决方案,通过重写PreTranslateMessage方法来屏蔽MFC对话框中ESC键直接关闭的功能,确保对话框的正常交互体验。
 

ESC键直接退出MFC对话框问题解决?
不知道大家是否也遇到这个问题,也在考虑应该如何解决?
今天做东西时,偶然发现有这个问题,如果想屏蔽掉的话,可以直接重写
PreTranslateMessage方法即可。如下:
重载这个方法,屏蔽原有的ESC直接关闭对话框的问题。
BOOL PreTranslateMessage(MSG* pMsg)
{
        // TODO: Add your specialized code here and/or call the base class
        if   (pMsg-> message==WM_KEYDOWN)
        {
                UINT   nkeyc=(UINT)(pMsg-> wParam);
                if(nkeyc==VK_ESCAPE)
                        pMsg-> wParam=0;
        }

        return CDialog::PreTranslateMessage(pMsg);
}

<think>我们正在讨论的是在VS2017 MFC对话框中取消ESC的默认退出功能。根据用户引用和之前的回答,有几种方法可以实现。用户特别关注如何禁止ESC退出程序。 从引用内容来看: 引用[1]和[2]提到可以通过重载PreTranslateMessage函数来屏蔽ESC。 引用[3]提到可以通过重写OnCancel函数(并去掉基类调用)来阻止ESC退出。 因此,我们可以提供两种方法: 方法一:重载PreTranslateMessage函数(在消息预处理阶段拦截ESC) 步骤: 1. 在对话框类中,通过类向导(Class Wizard)重载PreTranslateMessage虚函数。 2. 在PreTranslateMessage函数中添加对ESC的拦截。 示例代码: ```cpp BOOL CYourDialog::PreTranslateMessage(MSG* pMsg) { if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) { return TRUE; // 拦截ESC,不传递给默认处理 } return CDialogEx::PreTranslateMessage(pMsg); } ``` 方法二:重写OnCancel函数(阻止默认的取消行为) 步骤: 1. 在对话框类中,通过类向导重写OnCancel虚函数。 2. 在OnCancel函数中,不调用基类的OnCancel(即注释掉CDialogEx::OnCancel()),这样ESC按下时就不会关闭对话框。 示例代码: ```cpp void CYourDialog::OnCancel() { // 这里可以什么都不做,或者添加自定义处理 // 注意:一定不要调用基类的OnCancel,否则对话框仍会关闭 // CDialogEx::OnCancel(); } ``` 两种方法的比较: - 方法一:在消息预处理阶段就拦截了ESC,所以ESC不会触发OnCancel函数。 - 方法二:允许ESC触发OnCancel函数,但我们在OnCancel中阻止了关闭操作。 根据用户需求(禁止ESC退出程序),两种方法都可行。但需要注意: - 如果希望完全屏蔽ESC(即ESC按下后不做任何事情),使用方法一。 - 如果希望在ESC按下时执行一些自定义操作(但不关闭对话框),使用方法二。 此外,引用[3]还提到,如果没有重写OnOK函数,则Enter会调用OnOK函数导致对话框关闭。同理,我们可以用类似方法处理Enter(如果需要): - 重载PreTranslateMessage函数拦截Enter(VK_RETURN) - 或者重写OnOK函数并去掉基类调用。 现在,针对用户的问题(禁止ESC退出程序),我们给出详细步骤(以方法一为例,因为方法一可以同时处理多个按,且拦截更早): 步骤详解(方法一): 1. 打开类向导:在VS2017中,打开对话框类的头文件,右选择“类向导”(Class Wizard)。 2. 在“虚函数”选项卡中,找到“PreTranslateMessage”,点击“添加函数”。 3. 编辑生成的函数,添加上述代码。 注意:如果对话框基类是CDialog,则基类函数为CDialog::PreTranslateMessage;如果是CDialogEx,则为CDialogEx::PreTranslateMessage。 如果使用方法二,步骤类似: 1. 在类向导的“虚函数”选项卡中,找到“OnCancel”,添加函数。 2. 在函数体中不调用基类的OnCancel。 最后,考虑到用户可能还需要禁用其他按(如F1)或者自定义按功能,我们可以在相关问题中列出。 生成的相关问题: 1. 如何同时禁用ESC和Enter的默认关闭功能? 2. 如何在MFC对话框中为ESC设置自定义功能? 3. 如何禁用Alt+F4关闭MFC对话框? 4. 如何在MFC对话框中添加自定义热(如Ctrl+S)? 5. 如何恢复被禁用的默认对话框功能? 注意:在回答中,我们引用了用户提供的引用[1][2][3],在末尾添加引用标识。 </think>### VS2017 MFC项目中禁止ESC退出程序的两种方法 根据引用内容[1][2][3],禁止ESC退出程序主要有以下两种实现方案: #### ✅ 方法一:重载PreTranslateMessage函数(推荐) ```cpp BOOL CYourDialog::PreTranslateMessage(MSG* pMsg) { if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) { return TRUE; // 直接拦截ESC消息 } return CDialogEx::PreTranslateMessage(pMsg); } ``` **实现步骤**: 1. 在解决方案资源管理器中右击对话框类 → 选择"类向导" 2. 在"虚函数"选项卡中找到`PreTranslateMessage` → 点击"添加函数" 3. 在生成的函数中添加上述拦截代码 4. 编译运行后,ESC将被完全禁用[^1][^2] #### ✅ 方法二:重写OnCancel虚函数 ```cpp void CYourDialog::OnCancel() { // 1. 完全禁用退出: // 空实现(不调用基类方法) // 2. 自定义功能(示例): // if(MessageBox("确定要执行自定义操作吗?", "提示", MB_YESNO) == IDYES) // { // // 添加自定义逻辑 // } } ``` **实现步骤**: 1. 在类向导的"虚函数"选项卡中选择`OnCancel` 2. 点击"添加函数"生成重写 3. **关**:删除或注释掉`CDialogEx::OnCancel()`调用 4. 按需添加自定义逻辑或保持空实现[^3] --- ### 两种方案对比 | **特性** | 方法一 (PreTranslateMessage) | 方法二 (OnCancel) | |----------------|----------------------------------|--------------------------------| | 拦截阶段 | 消息预处理阶段(更早) | 命令执行阶段 | | 代码侵入性 | 低 | 中 | | 自定义扩展 | 可添加按响应逻辑 | 可替换为自定义功能 | | 适用场景 | 需完全禁用ESC | 需改变ESC行为 | > ⚠️ **重要提示**: > 若同时存在`OnCancel`和`PreTranslateMessage`实现,优先执行`PreTranslateMessage`。推荐使用方法一,因其能更彻底地阻止ESC的默认行为[^2][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值