如何防止我的基于 MFC 对话框的应用程序在 ESC 键后关闭,但允许其他控件处理它?

How to prevent my MFC dialog-based app from closing after ESC key, but allow other controls to process it?

我似乎找不到有效的解决方案来阻止基于对话框的 MFC 应用程序在用户按下键盘上的 ESC 键后关闭。我一直在寻找人们简单地覆盖 PreTranslateMessage 通知并阻止 VK_ESCAPE 的所有 WM_KEYDOWN 消息的代码,但这对我不起作用,因为这种方法会阻止 all 应用程序中的 ESC 击键。因此,例如,当用户打开一个下拉列表并想用 ESC 键关闭它时,它也会被阻止。或者,如果有人打开弹出菜单或 date-time/calendar 控件并尝试使用 ESC 击键等将其关闭,也会发生同样的情况。

那么我的问题是,如何防止 只有我的对话框 在按下 ESC 键后关闭?

Esc 通过 WM_COMMAND 自动路由到您的对话,ID 为 IDCANCEL。在 dlgcore.cpp 中有一个默认处理程序将终止您的对话(因此您的应用程序)如下所示:

void CDialog::OnCancel()
{
    EndDialog(IDCANCEL);
}

要阻止这种情况发生,只需自己添加一个 IDCANCEL 处理程序。例如,在您的对话框中 header 添加方法签名:

afx_msg void OnCancelOverride();

在您的对话消息映射中,为 IDCANCEL 添加路由:

ON_COMMAND(IDCANCEL,OnCancelOverride)

最后添加 OnCancelOverride 实现。如果 Esc 关闭,此示例实现不会退出,但允许从系统菜单 'Close' 选项退出。

void CMyDlg::OnCancelOverride() 
{
  // call base implementation if escape is not down

  if((GetKeyState(VK_ESCAPE) & 0x8000)==0)
    OnCancel();
}
  1. 你可以直接重写OnCancel方法什么都不写
  2. ON_WM_CLOSE()添加到消息映射,以便您可以通过单击右上角的 X 按钮退出应用程序。
  3. 在对话框 class 中添加方法 afx_msg void OnClose () header。
  4. 在对话框 class cpp 中添加如下代码: afx_msg void CDialogXXX::OnClose () { PostQuitMessage (0) ; CDialog::OnClose () ; }