PreTranslateMessage

转载 2011年10月15日 14:11:04

PreTranslateMessage

1. 函数原型(源自MSDN)

      virtual BOOL PreTranslateMessage(MSG* pMsg);

      功能:

      重载该函数可以实现窗口消息在派发给窗口函数TranslateMessage()DispatchMessage()之前的过滤.缺省的实现是完成加速键的翻译.因为您必须在你的重载版本中调用CWinApp:PreTranslateMessage()函数.

      MFC中,PreTranslateMessage()是虚函数,我们可以重载它来处理键盘和鼠标消息。

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

2. 说明

      该函数表示在消息处理(TranslateMessage()DispatchMessage())前所作的操作,如果函数返回值为TRUE,那么消息处理即终止,不会调用TranslateMessage()DispatchMessage()来翻译和分发消息给相应的窗口;若返回值为FALSE,才会调用翻译和分发消息函数。

      该函数是MFC消息控制流最具特色的地方,它是CWnd类的虚拟函数,通过重载这个函数,我们可以改变MFC的消息控制流程,甚至可以作一个全新的控制流出来。

      win32程序中,关于消息有两种传递方式:

      a. MFC消息,MFC会把所有的消息一条条放到一个AFX_MSG_MAP_ENTRY结构中,形成一个数组,该数组存放了所有的消息和与它们相关的参数。也可以说是放到消息队列里去。

      b. 采用SendMessage()或其他类似的方式向窗口直接发送的而不经过消息队列的消息。

    这两种方式中只有第一种(穿过消息队列的消息)才受PreTranslateMessage()影响,第二种消息并不会理睬PreTranslateMessage()的存在。

3. 其他

      PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗口的消息都要通过这里,比较常用,当你需要在MFC之前处理某些消息时,常常要在这里添加代码.

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

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

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

      三、在WindowProc里不能处理WM_CHAR消息。(WindowProc函数见MFC消息响应机制一文)

      四、SetWindowText会发送WM_CHAR给窗口。

      五、PeekMessageGetMessage的区别:

      GetMessage在没有消息的时候等待消息,效率低。PeekMessage没有消息的时候立刻返回,所以CPU占用率高。因为游戏不能靠Windows消息驱动,所以要用PeekMessage();

      在一个WIN32程序中,WINDOWS会将消息传递给相应的窗口。但是消息不是立即就被传递给相应的窗口,而是会从整个程序最顶层的窗口传递到下一级窗口,再传递到下一级窗口,直到传递给目标窗口。在整个过程中,有些消息,在某些特定的情况下,无法默认传递到目标窗口的。比如用户在EDIT控件中按下回车键,CANCEL键等,如果EDIT窗口之前有对话框窗口,对话框会默认处理回车消息(即响应ONOK函数,然后关闭对话框),然后退出消息传递。所以 EDIT会收不到。要解决这个问题,可以在EDIT窗口之前所有的对话框中重载PreTranslateMessage函数,然后在函数内加上:

 if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)    //如果消息类型为WM_KEYDOWN并且用户按下的是回车
         return FALSE;   
//不翻译消息,直接将消息传递下去。具体可查MSDN。注意,这里返回值不能为TRUE,TRUE的意思是翻译消息后退出消息传递,如此一来虽然也能避开对话框默认处理,但是会退出消息传递,这样EDIT控件照样得不到消息。(我一开始所犯的错误)

    如此,就可避开对话框默认处理,将消息传递下去。注意:只有对话框才会默认处理按下回车,CANCEL消息,其他控件窗口则不会,所以在其他窗口中不必重载PreTranslateMessage函数,当然如果重载了也不会错。

附:关于PreTranslateMessage()函数的小程序示例:

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;
       }

   }

}

PreTranslateMessage与WindowProc的区别

用PostMessage发送的消息要先经过PreTranslateMessage来处理,而SendMessage发送的消息直接交到WindowProc来处理。 键盘等消息在框架中在它进入vi...
  • movezzzz
  • movezzzz
  • 2014-02-17 20:17:53
  • 773

MFC中的PreTranslateMessage

最近用了一段时间的MFC,主要来做图像交互操作,缩放、拖拽、画框、删框、改变框等。用的最多的就是这个虚函数,我觉得我有必要总结一下,让自己更了解这个函数,以后用起来有个参考也更方便。 1.PreTr...
  • jiang111_111shan
  • jiang111_111shan
  • 2015-10-23 16:56:04
  • 2608

PreTranslateMessage()里怎么捕捉组合键例如:Ctrl+C

BOOL CMydilog::PreTranslateMessage(MSG* pMsg){// TODO: Add your specialized code here and/or call th...
  • kingpcn
  • kingpcn
  • 2007-11-23 13:07:00
  • 4748

Win32编程点滴之PreTranslateMessage与消息循环

转自 http://www.cnblogs.com/Greatest/archive/2009/08/25/1553623.html
  • ihc523
  • ihc523
  • 2014-06-07 10:48:53
  • 2756

VC PreTranslateMessage详解

1.函数原型:(MSDN) virtual BOOL PreTranslateMessage( MSG *pMsg ); 功能:     Override   this   func...
  • chanchaw
  • chanchaw
  • 2012-05-10 20:07:35
  • 5143

自己对PretranslateMessage的一点理解

给一个CDialog添加 WM_CHAR  --  OnChar 的响应: void Clearn_WMCHARDlg::OnChar(UINT nChar, UINT nRepCnt, UINT ...
  • liji_digital
  • liji_digital
  • 2015-12-17 21:37:21
  • 581

PreTranslateMessage为何不能使鼠标失效?

PreTranslateMessage为何不能使鼠标失效?  BOOL CDlgMediaPlay::PreTranslateMessage(MSG* pMsg) { if(WM_RBUTTONDOW...
  • littleline
  • littleline
  • 2005-01-04 12:45:00
  • 1658

PreTranslateMessage()函数捕获键盘按键消息

01. PreTranslateMessage函数,常用于屏蔽MFC对话框中默认的Enter和ESC消息函数原型:BOOL PreTranslateMessage(MSG* pMsg)用法举例:BOO...
  • bookish_2010_prj
  • bookish_2010_prj
  • 2010-09-09 17:25:00
  • 6825

关于VC的dialog框PreTranslateMessage不响应现象及解决办法

1.案例情况:1)dialog动态生成按钮 CButton* pBtn = new CButton();// 定义按钮   CRect rcBtn(10,10,40, 30); //按钮显示位置长30...
  • fjssharpsword
  • fjssharpsword
  • 2011-07-01 15:57:00
  • 8490

为手工添加MFC PreTranslateMessage 重载

在头文件中加  public: virtual BOOL PreTranslateMessage(MSG* pMsg);  然后在cpp 文件中重写  BOOL CGetcwndDlg::PreTra...
  • ssihc0
  • ssihc0
  • 2010-06-06 23:31:00
  • 3933
收藏助手
不良信息举报
您举报文章:PreTranslateMessage
举报原因:
原因补充:

(最多只允许输入30个字)