转载:https://blog.csdn.net/qq_35583007/article/details/62435002
一、添加消息处理函数PreTranslateMessage,此函数可以通过MFC ClassWizard添加
- BOOL CPreTranslateMessageDlg::PreTranslateMessage(MSG* pMsg)
- {
- if (pMsg->message==WM_LBUTTONDOWN)
- {
- MessageBox(“三三四四”);
- }
- return CDialog::PreTranslateMessage(pMsg);
- }
此函数为手动添加的消息函数,可通过pMsg->message来判断是什么消息,比如WM_LBUTTONDOWN是左键单击消息,那当单击左键时就会执行此函数,同样当敲击一下键盘也会执行PreTranslateMessage函数
关于PreTranslateMessage
MFC消息控制流最具特色的地方是CWnd类的虚拟函数PreTranslateMessage(),通过重载这个函数,我们可以改变MFC的消息控制流程,甚至可以作一个全新的控制流出来。只有穿过消息队列的消息才受PreTranslateMessage()影响,采用SendMessage()或其他类似的方式向窗口直接发送的而不经过消息队列的消息根本不会理睬PreTranslateMessage()的存在。
顾名思义,PreTranslateMessage就是消息发送给窗口之前,提前拦截消息,然后对消息进行处理(即,改变了MFC的消息控制流程)
要注意一下两点:
1、是否调用TranslateMessage()和DispatchMessage()是由一个名称为PreTranslateMessage()函数的返回值决定的,如果该函数返回TRUE,则不会把该消息分发给窗口函数处理。
2、传给PreTranslateMessage()的消息是未经翻译过的消息,它没有经过TranslateMessage()处理。可以在该函数中使用(pMsg->wParam==VK_RETURN)来拦截回车键。
再看看一下的例子:
BOOL CMyMessageView::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message==WM_LBUTTONDOWN)
{
MessageBox(“三三四四”);
}
if (pMsg->message==WM_MYMESSAGE) //这个是自定义消息,点击某个按钮时,会发送该消息~ 用PostMessage(WM_MYMESSAGE,IDC_BUTTON1);//发送之后立即返回
{
MyDialog dlg;
dlg.DoModal();
}
if (pMsg->message==WM_KEYDOWN)
{
switch (pMsg->wParam)
{
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
{
AfxMessageBox(“nihao!”);
}
return TRUE;
default:
break;
}
}
return CFormView::PreTranslateMessage(pMsg);
}
在上面的例子中,
1.鼠标按下时,会响应 MessageBox(“三三四四”);
2.键盘按下(并且是左、下、右)时,会响应AfxMessageBox(“nihao!”);
以上两个消息(鼠标按下的消息、按下键盘的消息),都是系统自带的消息~~易知,PreTranslateMessage改变了消息流程,让他们弹出对话框了
实际上,我们可以为这两个消息添加消息响应函数,OnLButtonDown,OnKeyDown
但是,有了PreTranslateMessage,这些消息响应函数就执行不到了
3.WM_MYMESSAGE是自定义消息~~我们也为它定义了消息响应函数OnMyMessage,但是,因为被PreTranslateMessage捕获了,所以先会执行PreTranslateMessage里面