关于怎样使对话框的Enter&Esc键消息失效

默认情况下Enter键消息会响应OnOKEsc键消息会响应OnCancel

可以参看dlgcore.cppCDialog中的消息映射

 1 BEGIN_MESSAGE_MAP(CDialog, CWnd)
2 ON_COMMAND(IDOK, &CDialog::OnOK)
3 ON_COMMAND(IDCANCEL, &CDialog::OnCancel)
4 END_MESSAGE_MAP()
5
6 void CDialog::OnOK()
7 {
8   if (!UpdateData(TRUE))
9   {
10     return;
11   }
12
13   EndDialog(IDOK);
14 }
15
16 void CDialog::OnCancel()
17 {
18   EndDialog(IDCANCEL);
19
}
20

还有WM_CLOSE消息(单击关闭按钮)的响应函数会调用OnCancel,具体关联的流程如下:

WM_CLOSE消息会调用CWnd::OnClose函数,在此函数中会POST一个WM_COMMAND,BN_CLICKED,IDCANCEL消息给对话框

SPY++可以看到,源码不可见。

所以,可行的方案是

()重载PreTranslateMessage函数

BOOL CYourDlg::PreTranslateMessage(MSG* pMsg)  

{

    if (pMsg->message == WM_KEYDOWN)

    {

        switch(pMsg->wParam)

        {

        case VK_RETURN:

            return TRUE;

        case VK_ESCAPE:

            return TRUE;

        default:

            break;

        }

    }

    return CDialog::PreTranslateMessage(pMsg);

}

()重载CDialog的两个虚函数OnOK&OnCancel使其什么也不做,

重载WM_CLOSE消息的处理函数并在其中调用EndDialog(IDCANCEL)

protected:

    virtual void OnOK();

    virtual void OnCancel();

void CChatWY_SrvDlg::OnOK()

{

}

void CChatWY_SrvDlg::OnCancel()

{

}

BEGIN_MESSAGE_MAP(CChatWY_SrvDlg, CDialog)

    ON_WM_CLOSE()

END_MESSAGE_MAP()

protected:

    afx_msg void OnClose();

void CYourDlg::OnClose()

{

    EndDialog(IDCANCEL);

}

关于Enter键如何与IDOK相关联:

1. 如果Dialog中某个Button拥有Foucs,则按Enter键会响应该按钮

Dialog按下某按钮该按钮就会获得焦点。

2. 如果该Dialog中,没有任何Button拥有focus,但是该Dialogdefault button,则敲回车键时会响应该Default ButtonDefault Button可以设置。

3. 如果该Dialog中,没有任何Button拥有focus,也没有Default Button,则敲回车键时,Windows为对话框提供了一个专用的键盘接口,专门用于对几个键进行处理,如:ENTER键,给对话框发送一条WM_COMMAND消息,参数wParam被设置成IDOK;而ESC键,给对话框发送一条WM_COMMAND的消息,参数wParam被设置成IDCANCEL

Note:我试图通过更改MFC的源码来实现,但发现不可行。更改MFC的源码根本不起作用,原因在于MFC的源码部分早就被编译成了二进制文件,我们在编译程序时只会编译我们自己写的代码部分,而调用之前早就编译好的MFC源码部分的二进制文件。

 

原文地址:https://www.cnblogs.com/Hisin/p/2378039.html