对话框Enter键与Esc键的处理问题

在MFC对话框中,经常会碰到按Enter或ESC键,对话框会被关闭的现象。
一、原因分析
MFC对话框Enter键消息机理:
1.如果Dialog中某个Button拥有Foucs,则按Enter键会响应该按钮。
在Dialog按下某按钮该按钮就会获得焦点。
2.如果Dialog中,没有任何Button拥有focus,但是Dialog有default button,则按Enter键时会响应Default Button,Default Button可以设置。
3.如果Dialog中,没有任何Button拥有focus,也没有Default Button,则按Enter键时,会给对话框发送一条WM_COMMAND消息,参数wParam被设置成IDOK(此时Windows为对话框提供了一个专用的键盘接口用于处理Enter按键消息)。

MFC对话框Esc键消息机理:
ESC键按下时,会给对话框发送一条WM_COMMAND的消息,参数wParam被设置成IDCANCEL。

WM_CLOSE消息机理:
WM_CLOSE消息(单击关闭按钮)会调用CWnd::OnClose函数,在此函数中会Send一个WM_COMMAND,wParam=IDCANCEL消息。
[源码不可见,用spy++可以看到]

我们查看源码看下CDialog对以上消息的处理:
BEGIN_MESSAGE_MAP(CDialog, CWnd)
  ON_COMMAND(IDOK, &CDialog::OnOK)
  ON_COMMAND(IDCANCEL, &CDialog::OnCancel)
END_MESSAGE_MAP()
 
void CDialog::OnOK()
{
    if (!UpdateData(TRUE))
    {
        return;
    }
 
    EndDialog(IDOK);
}

void CDialog::OnCancel()
{
    EndDialog(IDCANCEL);
}
二、解决方案
2.1重载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);
}
2.2重载CDialog的两个虚函数OnOK&OnCancel使其什么也不做,并重载WM_CLOSE消息的处理函数并在其中调用EndDialog(IDCANCEL)
protected:
    virtual void OnOK();
    virtual void OnCancel();

void CYourDlg::OnOK()
{
}

void CYourDlg::OnCancel()
{
}

BEGIN_MESSAGE_MAP(CYourDlg, CDialog)
    ON_WM_CLOSE()
END_MESSAGE_MAP()

protected:
    afx_msg void OnClose();

void CYourDlg::OnClose()
{
    EndDialog(IDCANCEL);
}

你可能感兴趣的:(对话框Enter键与Esc键的处理问题)