C++ 如何防止按Enter键和Escape键关闭MFC对话框?
我知道有一种方法可以防止MFC对话框在按下Enter键或Esc键时关闭,但我想知道该过程的更多细节以及所有常用的替代方法C++ 如何防止按Enter键和Escape键关闭MFC对话框?,c++,mfc,C++,Mfc,我知道有一种方法可以防止MFC对话框在按下Enter键或Esc键时关闭,但我想知道该过程的更多细节以及所有常用的替代方法 提前感谢您的帮助。当用户在对话框中按Enter键时,可能会发生两种情况: 该对话框有一个默认控件(请参见CDialog::SetDefID())。然后将带有此控件ID的WM_命令发送到对话框 该对话框没有默认控件。然后ID=IDOK的WM_命令被发送到对话框 对于第一个选项,默认控件的ID可能等于IDOK。然后,结果将与第二个选项中的结果相同 默认情况下,类CDialog具有
提前感谢您的帮助。当用户在对话框中按Enter键时,可能会发生两种情况:
CDialog::SetDefID()
)。然后将带有此控件ID的WM_命令发送到对话框CDialog
具有用于WM_命令(IDOK)
的处理程序,该处理程序将调用CDialog::OnOk()
,这是一个虚拟函数,默认情况下,它将调用关闭对话框的EndDialog(IDOK)
因此,如果要避免关闭对话框,请执行以下操作之一
IDOK
EndDialog()
的WM_命令(IDOK)
SetDefID()
,ESC键是硬编码的。因此,要避免关闭对话框,请执行以下操作:
EndDialog()
的WM_命令(IDCANCEL)
CDialog::OnCancel()
,不调用基本实现有一个替代上一个答案的选项,如果您仍希望使用“确定/关闭”按钮,该选项非常有用。如果重写PreTranslateMessage函数,则可以使用VK_ESCAPE/VK_RETURN,如下所示:
BOOL MyCtrl::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_KEYDOWN )
{
if(pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
{
return TRUE; // Do not process further
}
}
return CWnd::PreTranslateMessage(pMsg);
}
我只是重写OnOk事件,而不是将消息传递给父对话框,什么也不做
这样做基本上很简单:
void OnOk() override { /*CDialog::OnOK();*/ }
这将防止在按回车/回车键时关闭对话框。请确保您没有定义自定义ID 2,因为已为转义定义了
2
,我想为回车定义了1
?如果我错了,请纠正我。森林和树木的答案很好。除了一个由@oneworld解决的情况。您需要筛选不适用于对话框窗口的消息:
BOOL CDialogDemoDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->hwnd == this->m_hWnd && pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
{
return TRUE; // Do not process further
}
}
return CWnd::PreTranslateMessage(pMsg);
}
记住在头文件中添加
virtual
不确定您想在这里完成什么,但最好使用WM_GETDLGCODE
。您的解决方案也有一些缺点,必须记住。例如,如果用户希望在应用程序中使用ESC关闭DropDownList,他将无法再这样做。Enter也是如此。他不能再使用它与UI组件交互,例如完成选择。鉴于有两个投票率很高的答案似乎解决了这个问题,我不确定这是什么,因为不清楚。对于没有投票线索的人来说,很容易将问题关闭为不清楚。我想阻止ESC关闭对话框。但是,在OnCommand中阻止它或在OnCancel中过度隐藏都会阻止click X关闭对话框。@Zhang:我上次使用MFC已经有一段时间了,但是IIRC按X键会发送一个WM\u CLOSE
,默认情况下会转换成WM\u命令(IDCANCEL)
。你可以通过重写OnCancel()
来做你想做的事情,不做任何事情添加一个直接执行EndDialog(IDCANCEL)
的OnClose()
。。。到底为什么微软在MFC中包含如此模糊的行为?是否值得将其硬编码到基类中,而不是显式地为处理程序添加一行代码?