PreTranslateMessage和TranslateMessage区别

PreTranslateMessage和TranslateMessage区别PreTranslate 是消息在送给 TranslateMes 函数之前被调用的 绝大多数本窗口的消息都要通过这里 比较常用 当需要在 MFC 之前处理某些消息时 常常要在这里添加代码 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp MFC 消息控制流最具特色的地方是 CWnd 类的虚拟函数 PreTranslate 通过重载这个函数 可以改变 MFC 的消息控制流程 甚至可以

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

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

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

传给PreTranslateMessage()的消息是未经翻译过的消息,它没有经过TranslateMessage()处理。可以在该函数中使用(pMsg->wParam==VK_RETURN)来拦截回车键。wParam中存放的是键盘上字符的虚拟码。 

PeekMessage和GetMessage的区别: 

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

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

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

     PretranslateMessage 的实现,不得不谈到MFC消息循环的实现。MFC通过CWinApp类中的Pumpmessage函数实现消息循环,但是实际的消息循环代码位于 CWinThread中,CWinApp只是从CWinThread继承过来。其简化后的代码大概如下: 
  BOOL CWinThread::PumpMessage() 
  {
 
  _AFX_THREAD_STATE *pState = AfxGetThreadState(); 
   
  ::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL)) 
   
  if (!AfxPreTranslateMessage(&(pState->m_msgCur))) 
  {
 
  ::TranslateMessage(&(pState->m_msgCur)); 
  ::DispatchMessage(&(pState->m_msgCur)); 
  } 
  return TRUE; 
  } 
   可以看到,PumpMessage在实际的TranslateMessage和DispatchMessage发生之前会调用 AfxPreTranslateMessage,AfxPreTranslateMessage又会调用 CWnd::WalkPreTranslateTree(虽然也会调用其他函数,但是这个最为关键),其代码如下: 
  BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg) 
  {
 
  ASSERT(hWndStop == NULL || ::IsWindow(hWndStop)); 
  ASSERT(pMsg != NULL); 
   
  // walk from the target window up to the hWndStop window checking 
  // if any window wants to translate this message 
   
  for (HWND hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd)) 
  {
 
  CWnd* pWnd = CWnd::FromHandlePermanent(hWnd); 
  if (pWnd != NULL) 
  {
 
  // target window is a C window 
  if (pWnd->PreTranslateMessage(pMsg)) 
  return TRUE; // trapped by target window (eg: accelerators) 
  } 
   
  // got to hWndStop window without interest 
  if (hWnd == hWndStop) 
  break; 
  } 
  return FALSE; // no special processing 
  } 
   
  可以看到,代码还是很直接的。从接受到消息的窗口层层往上遍历,并调用PretranslateMessage看是否返回TRUE,是则结束,否则继续。 
  这里有一个地方非常关键:CWnd *pWnd = CWnd::FromHandlePermanent(hWnd) 这一句代码从当前AfxModuleThreadState拿到Permanent句柄表,从而找到hWnd对应的CWnd 

MFC 中PreTranslateMessage是GetMessage(…)函数的下一级操作,即GetMessage(…)从消息队列中获取消息 后,交由PreTranslateMessage()处理,若其返回FALSE则再交给TranslateMessage和 DispatchMessage处理(进入WindowProc);   
如果用SendMessage,   则消息直接交到WindowProc处理,所以GetMessage不会取得SendMessage的消息,当然PreTranslateMessage也就不会被调用。   [Page]
如果用PostMessage,则消息进入消息队列,由GetMessage取得,PreTranslateMessage就有机会进行处理。






























































版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227233.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午9:38
下一篇 2026年3月16日 下午9:39


相关推荐

  • RT-thread —- FinSH 控制台

    RT-thread —- FinSH 控制台一、介绍FinSH是RT-Thread的命令行组件(shell),有了shell,就像在开发者和计算机之间架起了一座沟通的桥梁,开发者能很方便的获取系统的运行情况,并通过命令控制系统的运行。特别是在调试阶段,有了shell,开发者除了能更快的定位到问题之外,也能利用shell调用测试函数,改变测试函数的参数,减少代码的烧录次数,缩短项目的开发时间。FinSH支持两种输入模式…

    2022年5月22日
    58
  • Android中View绘制流程以及invalidate()等相关方法分析

    Android中View绘制流程以及invalidate()等相关方法分析

    2021年11月29日
    43
  • iconst、bipush、sipush、ldc指令的区别

    iconst、bipush、sipush、ldc指令的区别文章目录 1 前言 2 iconst3 bipush4 sipush5 ldc 转载 1 前言 JVM 中 int 类型数值 根据取值范围将入栈的字节码指令就分为 4 类 取值 1 5 采用 iconst 指令 取值 128 127 采用 bipush 指令 取值 32768 32767 采用 sipush 指令 取值 采用 ldc 指令 2 iconst 当 int 取值 1 5 时 JVM 采用 iconst 指令将常量压入栈中 定义 Test ja

    2026年3月26日
    3
  • mysql储存过程怎么写_oracle的存储过程写法

    mysql储存过程怎么写_oracle的存储过程写法存储过程写法是什么存储过程的写作是什么,存储过程的编写如下:1.用代码[创建进程名]创建一个存储过程;2.用[EXECSP_NAME]代码调用存储过程。操作环境:Windows7系统,微软visualc2015版本,戴尔G3电脑。存储过程写法是:1、创建存储过程创建过程sp_name@[参数名][类型],@[参数名][类型]作为开始..结束以上格式也可以缩写为:创建进程sp_nam…

    2025年6月22日
    5
  • Claude Code 低成本使用方案来了,国内可直连!!

    Claude Code 低成本使用方案来了,国内可直连!!

    2026年3月16日
    2
  • gatekeeper调研

    gatekeeper调研动机及简介如果你的组织在运行 Kubernetes 那么你可能一直在寻找控制终端用户可以在集群上做什么 以及确保集群符合公司或组织政策的方法 这些政策可能是用来满足治理和法律需求 或者执行最佳实践和组织约定 使用 Kubernetes 你如何在不牺牲开发灵活性和操作独立性的情况下确保遵从性 例如 你可以执行以下政策 所有镜像必须来自已批准的存储库 所有 pod 都必须有资源限制 所有

    2026年3月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号