九:PreTranslateMessage

来源:互联网 发布:淘宝联盟用不了 编辑:程序博客网 时间:2024/06/02 10:12

在MFC中,PreTranslateMessage是虚函数,我们可以重载它来处理键盘和鼠标消息。 
PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗口的消息都要通过这里,比较常用,当需要在MFC之前处理某些消息时,常常要在这里添加代码. 

MFC消息控制流最具特色的地方是CWnd类的虚拟函数PreTranslateMessage(),通过重载这个函数,我们可以改变MFC的消息控制流程,甚至可以作一个全新的控制流出来。只有穿过消息队列的消息才受PreTranslateMessage()影响,采用SendMessage()或其他类似的方式向窗口直接发送的而不经过消息队列的消息根本不会理睬PreTranslateMessage()的存在。

      一、是否调用TranslateMessage()DispatchMessage()是由一个名称为PreTranslateMessage()函数的返回值决定的,如果该函数返回TRUE,则不会把该消息分发给窗口函数处理。

二、传给PreTranslateMessage()的消息是未经翻译过的消息,它没有经过TranslateMessage()处理。可以在该函数中使用(pMsg->wParam==VK_RETURN)来拦截回车键。

三、在WindowProc里不能处理WM_Char消息。

四、SetWindowText会发送WM_Char给窗口。

五、PeekMessageGetMessage的区别:

GetMessage在没有消息的时候等待消息,cpu当然低

PeekMessage没有消息的时候立刻返回,所以cpu占用率高。

因为游戏不能靠windows消息驱动,所以要用PeekMessage();

       六,PreTranslateMessage只能处理消息队列中的消息,也就是由PostMessage发出的消息/鼠标键盘消息等.
             SendMessage发送的消息并不放在消息队列中,而是直接调用处理函数进行处理,所以这种消息用PreTranslateMessage的捕获不到的,如WM_KIllFOCUS和WM_SETFOCUS.

在MFC中,PreTranslateMessage是虚函数,我们可以重载它来处理键盘和鼠标消息。在sdk中,这又有所不同,我们必须在回调函数中LRESULT   CALLBACK   WndProc(HWND   hWnd,   UINT   message,   WPARAM   wParam,   LPARAM   lParam)处理消息:它和PreTranslateMessage起的作用是类似的。只是MFC封装的更好而已。

重载该函数可以实现窗口消息在派发给窗口函数TrnaslateMessage和DispatchMessae()之前的过滤.缺省的实现是完成加速键的翻译.因为您必须在你的重载版本中调用CWinApp:PreTranslateMessage()函数.很显然,在SDK中在TranslateMassage()函数之前来实现该功能.  
例如:
virtual BOOL PreTranslateMessage(MSG* pMsg);
void CstrtestDlg::OnLButtonDown(UINT   nFlags,   CPoint   point)  //鼠标焦点 
 CRect rtCurMain(0,0,0,0);
 GetWindowRect(&rtCurMain);
 int nW = rtCurMain.Width();
 int nH = rtCurMain.Height();
 CRect rtDrag(0,0,nW-50,54);  //右边几个按钮的宽度,黑色标题栏的高度
 if (PtInRect(&rtDrag,point))
 {
  //非标题栏移动整个窗口
  ::SendMessage(this->GetParent()->GetSafeHwnd(),WM_SYSCOMMAND,0xF012,0);
  ::PostMessage(this->GetParent()->GetSafeHwnd(),WM_LBUTTONUP,NULL,MAKELPARAM(point.x,point.y));
 }
 CWnd::OnLButtonDown(nFlags,   point); 
}
例子2:s  
BOOL CUserDlg::PreTranslateMessage(MSG* pMsg)
{
    
if(pMsg->message == WM_KEYDOWN) //判断是否有按键按下
    {
       
switch(pMsg->wParam)
       
{
          
case VK_DOWN:     //表示是方向键中的向下的键
              
// code here 
               break;
          
case VK_UP:      //表示是方向键中的向上的键
               
// code here 
               break;
          
default:
               
break;
       }

   }

}
键盘快捷键
virtual BOOL PreTranslateMessage(MSG* pMsg);
BOOL CSSQDlg::PreTranslateMessage(MSG* pMsg)
{
 //用PreTranslateMessage的方法,
 if(pMsg->message==WM_KEYDOWN&&pMsg->wParam==VK_RETURN) //VK_ESCAPE esc快捷键  VK_RETURN enter快捷键
 {//pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST //任意键快捷键
  AfxMessageBox(_T("Ctrl + Q 被按下"));
  return TRUE;
 }
 return CDialog::PreTranslateMessage(pMsg);
}
原创粉丝点击