默认情况下Enter键消息会响应OnOK,Esc键消息会响应OnCancel
可以参看dlgcore.cpp中CDialog中的消息映射
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,但是该Dialog有default button,则敲回车键时会响应该Default Button,Default Button可以设置。
3. 如果该Dialog中,没有任何Button拥有focus,也没有Default Button,则敲回车键时,Windows为对话框提供了一个专用的键盘接口,专门用于对几个键进行处理,如:ENTER键,给对话框发送一条WM_COMMAND消息,参数wParam被设置成IDOK;而ESC键,给对话框发送一条WM_COMMAND的消息,参数wParam被设置成IDCANCEL。
Note:我试图通过更改MFC的源码来实现,但发现不可行。更改MFC的源码根本不起作用,原因在于MFC的源码部分早就被编译成了二进制文件,我们在编译程序时只会编译我们自己写的代码部分,而调用之前早就编译好的MFC源码部分的二进制文件。