zoukankan      html  css  js  c++  java
  • MFC消息截获之pretranslatemessage

    前几天,查了一个batch的问题,问题大致是这样,父窗口消息一个鼠标消息,弹出一个模态框,CPU负荷就飚升到100%(双核就是50%),非常怪异,用windbg,分析哪个线程占用CPU,定位到鼠标响应函数,也就是弹出模态框的函数,windbg提供的信息有限,只能自己分析,经过各种尝试,发现与模态框里面的控件无关,所以应该还是父窗口的问题,仔细看了下父窗口的代码,发现父窗口为了截获F1按下的消息,而重载了Pretranslatemessage,而Pretranslatemessage返回值都是真!!就是这个返回值导致的,下面我们来分析下,为什么影响这么大:

    以模态对话框作说明
    [code]
    MyDiag test = new MyDiag(NULL); 
    test.DoModal();
    [/code]
    我们重点看DoModal后面windows做了什么,简单来说应该做了两件事:
    1)发送一个DlgInit消息,这个消息最终的响应就是对话框的OnInitDialog(),创建成功后返回窗口句柄
    如果DoModal后窗口还没显示出来就崩溃或者assert,OnInitDialog里面的代码怀疑最大,可能里面某些控件有问题,譬如没有注册,找不到等
    2)进入消息循环,窗口就可以消息处理各种消息响应了
    消息循环的关键代码如下:
    [code]
    do 

       if ( !PreTranslateMessage(&msg)) 
        { 
          ::TranslateMessage(&msg); 
          ::DispatchMessage(&msg); 
        } 
    }while(::PeekMessage(pMsg,NULL,NULL,NULL,PM_NOREMOVE));
    [/code]
    从2的代码中我们可以看到,如果PreTranslateMessage为真,那就进入不会进TranslateMessage,跟不用说是消息的分发与响应了,这也就是为什么可以通过重写PreTranslateMessage可以消息队列中的消息,甚至是重定向消息,
    PreTranslateMessage为真后,这个消息循环就空转,像一个死循环,为什么说像,而不是是,是因为windows会处理是不是idle的情况,当创建一个模态框后,焦点转到模态框,父窗口这是应该无法处理到idle的情况,而进入死循环,导致负荷一下飚升到50%(双核),修改PreTranslateMessage,出了要截获的消息,其他消息返回假,让消息循环继续处理消息。

    http://blog.csdn.net/lizheng308/article/details/36385241

  • 相关阅读:
    8张图带你轻松温习 Java 知识.md
    关于 Java 序列化你不知道的 5 件事
    为什么 String 是不可变的?
    如何使用 Nginx 优雅地限流?
    JAVA泛型编程笔记
    java_接口的应用
    java_抽象类应用
    深入理解Java的接口和抽象类
    java_重写与重载的区别
    Java:按值传递还是按引用传递详细解说
  • 原文地址:https://www.cnblogs.com/findumars/p/5086780.html
Copyright © 2011-2022 走看看