Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何防止按Enter键和Escape键关闭MFC对话框?_C++_Mfc - Fatal编程技术网

C++ 如何防止按Enter键和Escape键关闭MFC对话框?

C++ 如何防止按Enter键和Escape键关闭MFC对话框?,c++,mfc,C++,Mfc,我知道有一种方法可以防止MFC对话框在按下Enter键或Esc键时关闭,但我想知道该过程的更多细节以及所有常用的替代方法 提前感谢您的帮助。当用户在对话框中按Enter键时,可能会发生两种情况: 该对话框有一个默认控件(请参见CDialog::SetDefID())。然后将带有此控件ID的WM_命令发送到对话框 该对话框没有默认控件。然后ID=IDOK的WM_命令被发送到对话框 对于第一个选项,默认控件的ID可能等于IDOK。然后,结果将与第二个选项中的结果相同 默认情况下,类CDialog具有

我知道有一种方法可以防止MFC对话框在按下Enter键或Esc键时关闭,但我想知道该过程的更多细节以及所有常用的替代方法


提前感谢您的帮助。

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

  • 该对话框有一个默认控件(请参见
    CDialog::SetDefID()
    )。然后将带有此控件ID的WM_命令发送到对话框
  • 该对话框没有默认控件。然后ID=IDOK的WM_命令被发送到对话框
  • 对于第一个选项,默认控件的ID可能等于IDOK。然后,结果将与第二个选项中的结果相同

    默认情况下,类
    CDialog
    具有用于
    WM_命令(IDOK)
    的处理程序,该处理程序将调用
    CDialog::OnOk()
    ,这是一个虚拟函数,默认情况下,它将调用关闭对话框的
    EndDialog(IDOK)

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

  • 将默认控件设置为非
    IDOK
  • 将处理程序设置为不调用
    EndDialog()
    WM_命令(IDOK)
  • 重写CDialog::OnOk(),不调用基本实现
  • 关于IDCANCEL,它与此类似,但没有等效的
    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中包含如此模糊的行为?是否值得将其硬编码到基类中,而不是显式地为处理程序添加一行代码?