`

MFC全接触(三)

阅读更多

       昨天"问题男"老大给我的那篇post:噢,我的第一个基于SDK的窗口写了回复:“为何要PeekMessage呢?这样会令你的程序占用能占用的所有cpu时间,不如GetMessage,在没有消息时线程将被suspend。”这个回复让我思考了很久,也让我有了更多收获。真的很喜欢这种感觉,自己写下了一些简单而不成熟的想法,高手看到了又不吝赐教,正是大家这种知识共享的精神让我每天都有莫大的收获,真的很感谢!有点跑题了,呵呵~~
        说实在的,当时在运行自己写的例子的时候,确实发现CPU时间被耗尽了,系统运行得很慢,当时还真的没有反应过来是怎么回事,而且由于当时关注的问题并不在此,也没有去多想,只是想着随后要看一下基于MFC的程序运行会不会也是占用那么多的CPU时间(虽然当时我就知道答案肯定是不会的,呵呵)。直至看到了以上回复的时候,脑袋瓜受到了激发,一些原先完全割裂开的认识被这个回复联系到了一起。
        首先,刚开始接触PeekMessage和GetMessage的时候,文档告诉我PeekMessage是一个具有线程异步行为的函数,不管消息队列中是否有消息的,函数都会立即返回。而GetMessage则是一个具有线程同步行为的函数,如果消息队列中没有消息的话,函数就会一直等待,直到消息队列中至少有一条消息的时候,才会返回。先不管线程同步或者异步的话题,光看PeekMessage无论什么情况下都会返回,就会知道例子中的消息处理代码在消息队列中没有消息的时候,会不断的循环执行,就相当一个死循环,CPU不耗尽才怪呢。
        其次,正是"问题男"老大的回复让我想起了MFC中的消息处理机制:在那里不也用了PeekMessage函数到消息队列中取消息吗?那她到底是怎样避免死循环的出现的呢?于是,我再次回到CWinThread类中的Run函数中去看个究竟:

for (;;)
{
    
// phase1: check to see if we can do idle work
    while (bIdle &&!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
    
{
        
// call OnIdle while in bIdle state
    if (!OnIdle(lIdleCount++))
        bIdle 
= FALSE; // assume "no idle" state
    }


    
// phase2: pump messages while available
    do
    
{
        
// pump message, but quit on WM_QUIT
    if (!PumpMessage())
        
return ExitInstance();

    
// reset "no idle" state after pumping "normal" message
    if (IsIdleMessage(&m_msgCur))
    
{
        bIdle 
= TRUE;
        lIdleCount 
= 0;
    }


    }
 while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}
    

        代码中的bIdle的初始值是TRUE,如果PeekMessage返回值为FALSE,也就是当队列中没有消息的时候,那么while中的整个条件语句为TRUE,就会去调用OnIdle函数。由于lIdleCountOnIdle作为OnIdle函数的入参,且初始值为0,而返回的语句则是return lCount < 0,也就是说OnIdle返回值肯定是FALSE,那么bIdle就被赋值为FALSE了,自然就跳出了循环。接着就再进入下一个循环,通过PumpMessage方法去取得消息,而PumpMessage中实质就是调用了GetMessage方法去获得消息。总之在两个循环当中,PeekMessage的作用就象是探路石一样,去check一下队列中的是否有消息,有的话,是怎样的消息,但是她并没有将消息从队列中移除,我们可以通过PeekMessage方法中的最后一个参数就可以看出了。同时,两个循环也是交替进行的,象第二个循环,当消息队列中没有消息的时候,也会再一次回到一个循环。MFC之所以这样设计是希望能够通过OnIdle方法去处理当该窗体所属的线程处于空闲状态的情况,同时也保证了线程不会因为GetMessage而进入休眠状态。
  

分享到:
评论

相关推荐

    MFC 三态树制作步骤和源码

    下面我们将详细讨论MFC三态树的制作步骤、源码解析以及相关的编程知识。 首先,我们来看制作三态树的基本步骤: 1. **创建MFC AppWizard项目**: 使用Visual Studio(例如VC++6.0),创建一个新的MFC AppWizard...

    MFC第三方类

    2. **网络通信类**:MFC本身对网络编程的支持相对有限,第三方类库如WTL(Windows Template Library)或者ASIO(异步I/O库)可以增强MFC的网络通信能力,支持TCP/IP、HTTP、FTP等协议。 3. **数据库访问类**:MFC...

    C MFC第三方控件

    MFC 第三方控件, 可以美化界面!!!

    在MFC中画三角形

    在MFC(Microsoft Foundation Classes)框架中,开发人员可以利用其强大的图形用户界面(GUI)功能来创建应用程序。本篇文章将深入探讨如何在MFC单文档应用中实现一个功能,即通过点击菜单栏,允许用户使用鼠标来画...

    MFC绘制三角形(带橡皮筋功能)

    在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC) 库来创建一个具有橡皮筋效果的三角形绘制程序。MFC 是 Microsoft 提供的一套 C++ 类库,用于简化 Windows API 的使用,使得开发者能更方便地构建...

    计算机图形学——基于MFC三维图形开发 孔令德版

    在本资源中,"计算机图形学——基于MFC三维图形开发 孔令德版",作者孔令德提供了一套针对MFC(Microsoft Foundation Classes)框架的三维图形编程教程,帮助学习者深入理解计算机图形学在实际应用中的实现方式。...

    MFC实现三视图

    MFC实现三视图主要是为了在图形用户界面中展示一个对象或模型的不同侧面,例如在工程设计、3D建模等领域,常见的是前视图、侧视图和俯视图。这种功能常用于CAD(计算机辅助设计)软件,帮助用户从不同角度观察和编辑...

    MFC内嵌第三方EXE窗口

    在本文中,我们将深入探讨如何在Microsoft Foundation Class (MFC) 应用程序中内嵌第三方的EXE程序,如记事本(Notepad.exe),并解决与之相关的刷新、移动等问题。MFC是Microsoft为Windows开发应用程序提供的一套C++...

    MFC OpenGL 三维模型旋转

    在MFC中用 OpenGL 实现三维模型旋转

    mfc嵌入第三方exe.zip

    本压缩包文件“mfc嵌入第三方exe.zip”可能包含了一个关于如何在MFC应用程序中嵌入并运行第三方的EXE执行文件的示例或教程。 "嵌入第三方exe"通常是指在主程序中动态加载并执行另一个独立的可执行文件,这种方式常...

    VS2010中MFC利用TeeChart控件实现画三维图

    本文将深入探讨如何利用MFC(Microsoft Foundation Classes)框架结合TeeChart控件来实现三维图形的绘制。 TeeChart是一款强大的图表控件,它提供了丰富的图表类型,包括二维和三维图表,适用于Windows、Web以及...

    MFC 内嵌第三方Exe程序 VC2010

    本项目探讨了一个特殊的技术:如何在MFC应用程序中内嵌并运行一个第三方的EXE程序,使其作为子窗口展示。这个技术可以增强应用程序的功能,提供更丰富的用户体验。 首先,"MFC内嵌第三方Exe程序"涉及到的主要概念是...

    计算机图形学(MFC)-三维图形变换(立方体)

    在本资源中,我们关注的是三维图形变换,特别是在MFC(Microsoft Foundation Classes)框架下的应用。MFC是微软提供的一套面向对象的类库,用于简化Windows应用程序的开发,特别是图形用户界面(GUI)的应用。 三维...

    MFC实现树形控件TreeCtrl三态选择树

    在这个话题中,我们将深入探讨如何利用MFC来实现一个具有三态选择功能的TreeCtrl。 首先,三态选择树控件不同于普通的二态(全选或未选)树控件,它还包括了一个第三状态,即部分选中状态。这在处理复杂的逻辑选择...

    MFC下的三维模型显示软件

    本项目利用MFC创建了一个专门用于显示三维模型的软件,使得用户能够观察和交互3D模型。以下是对这个"三维模型显示软件"的详细解读: 1. **MFC框架**:MFC是一个C++类库,它封装了Windows API,提供了窗口、对话框、...

    MFC 皮肤库软件美化mfc界面

    MFC(Microsoft Foundation Classes)是微软提供的一套C++类库,用于简化Windows应用程序的开发。在MFC中,我们通常使用它来构建基于Windows API的桌面应用。然而,MFC默认的用户界面(UI)可能显得较为单调,无法...

    MFC中使用TeeChart绘制三维曲线

    以空间螺旋线为例,展示MFC中使用TeeChart绘制三维曲线的程序。包含https://blog.csdn.net/carlos_soler/article/details/78614054#7930033中的源程序

    绘制三维曲面的MFC程序

    本项目"绘制三维曲面的MFC程序"是利用MFC实现的一个可视化工具,能够将三维空间中的数据转换并显示为屏幕上的二维图像。 首先,我们需要理解三维坐标到二维屏幕坐标的转换过程。在三维空间中,每个点都有三个坐标(x...

    OpenGL+MFC显示三维点云中每一个点的法向量,Release版本

    相应的博客链接:OpenGL+MFC对三维点云的法向量实现可视化 - HW140701的博客 - CSDN博客 http://blog.csdn.net/hw140701/article/details/77899725

    【转】mfc鼠标拖动三维旋转

    在MFC(Microsoft Foundation Class)库中开发一个支持鼠标拖动进行三维旋转的应用程序是一项常见的任务,尤其是在构建交互式3D图形用户界面时。MFC是Microsoft为Windows平台提供的C++类库,它封装了Windows API,...

Global site tag (gtag.js) - Google Analytics