如何防止在Enter和Escape键上关闭MFC对话框?

时间:2013-07-24 07:58:12

标签: c++ mfc

我知道在按下 Enter Esc 键时阻止MFC对话框关闭的一种方法,但我想了解更多有关该过程的详细信息,所有常见的替代方法。

提前感谢您的帮助。

5 个答案:

答案 0 :(得分:31)

还有一个替代上一个答案,如果您希望仍然有一个确定/关闭按钮,这将非常有用。如果覆盖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);
}

答案 1 :(得分:30)

当用户在对话框中按Enter键时,可能会发生两件事:

  1. 该对话框具有默认控件(请参阅CDialog::SetDefID())。然后将具有此控件ID的WM_COMMAND发送到对话框。
  2. 该对话框没有默认控件。然后将ID = IDOK的WM_COMMAND发送到对话框。
  3. 使用第一个选项,可能会发生默认控件的ID等于IDOK。然后结果将与第二个选项中的结果相同。

    默认情况下,类CDialog有一个WM_COMMAND(IDOK)的处理程序,用于调用CDialog::OnOk(),这是一个虚函数,默认情况下调用EndDialog(IDOK)关闭对话框。

    因此,如果您想避免关闭对话框,请执行以下操作之一。

    1. 将默认控件设置为IDOK以外的其他控件。
    2. 将处理程序设置为不调用WM_COMMAND(IDOK)的{​​{1}}。
    3. 覆盖EndDialog(),不要调用基础实现。
    4. 关于IDCANCEL,它类似,但没有等效的CDialog::OnOk(),并且ESC键是硬编码的。所以要避免关闭对话框:

      1. 将处理程序设置为不调用SetDefID()的{​​{1}}。
      2. 覆盖WM_COMMAND(IDCANCEL),不要调用基础实现。

答案 2 :(得分:0)

我只是重写OnOk事件,而不是将消息传递给父对话框,什么也不做。
因此,这样做基本上很简单:

void OnOk() override { /*CDialog::OnOK();*/ }

这应该防止在按回车/输入键时关闭对话框。

答案 3 :(得分:0)

确定您没有#define CUSTOM_ID 2是因为已经定义了2用于转义,并且我认为1已经定义用于回车吗?如果我错了请纠正我。

答案 4 :(得分:0)

@ the-forest-and-the-trees的答案非常好。 @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