一般主界面无响应的解决方案是,对于计算量过大的方法,另开工作者线程,如下:

MFC支持两种线程:用户界面线程和工作者线程。

(1)用户界面线程:通常用于处理用户输入,响应由用户产生的事件和消息。用户界面线程通常有窗口,有自己的消息循环。CWinApp是一个用户界面线程对象的例子,因为它是从CWinThread派生出来的,而且要处理用户产生的事件和消息。

(2)工作者线程:通常用于处理无需用户输入的任务,如计算。工作者线程没有窗口,因此不需要处理消息。

必须注意的是,可能会出现多个线程同时访问同一个对象的情况。例如,一个线程正在修改一个对象,而另一个线程要读取这个对象,这时就会出现问题。所以,必须采取线程同步的方法来避免此类问题的发生。这也是多线程程序之所以复杂的一个重要原因。

工作者线程通常用于后台的需耗费较长时间的工作,例如:计算、后台打印等。创建一个线程专门处理此类工作,用户就可以进行其他工作而无需等待。

一个MFC线程,不管是工作者线程还是用户界面线程,都是调用AfxBeginThread创建并初始化。只是AfxBeginThread被重载成两个版本,一个用于工作者线程,一个用于用户界面线程。

创建工作线程的函数原型是:CWinThread * AfxBeginThread(AFX_THREADPROC pfnThreadProc,LPVOIDpParam ,int nPriority = THREAD_PRIORITY_NORMAL,UINT nStacksize=0,DWORDdwCreateFlags =0,LPSECURITY_ATTRIBUTES lpSecurityAttris = NULL);

pfnThreadProc是线程函数指针,工作线程对应一个线程函数

创建用户界面线程原型:CWinThread * AfxBeginThread(CRuntimClass * pThreadClass, intnPriority = THREAD_PRIORITY_NORMAL,UINT nStacksize=0,DWORD dwCreateFlags =0,LPSECURITY_ATTRIBUTESlpSecurityAttris = NULL);

pThreadClass是CWinTHread的派生类创建的

但是另开工作者线程,需要pfnThreadProc为全局方法,或类静态方法,这样就限定了使用范围,但是我们可以采用PeekMEssage方法嵌入在主线程中,解决此种UI无响应的状态,如下:

GetMessage不将控制传回给程序,直到从程序的消息队列中取得消息,但是PeekMessage总是立刻传回,而不论一个消息是否出现。当消息队列中有一个消息时,PeekMessage的传回值为TRUE(非0),并且将按通常方式处理消息。当队列中没有消息时,PeekMessage传回FALSE(0)。

[cpp]  view plain copy print ?
  1. <span style="font-family:Microsoft YaHei;"><span style="font-family:Courier New;"><span style="font-family:Comic Sans MS;font-size:14px;">BOOL PeekMessage(
  2. LPMSG IpMsg, // 检索到的消息
  3. HWND  hWnd,  // 窗口指向
  4. UINT  wMSGfilterMin,// 消息范围的下界限参数
  5. UINT  wMsgFilterMax,// 上界限参数
  6. UINT  wRemoveMsg     // 消息在被检索之后要如何处理
  7. );
  8. lpMsg:接收消息信息的MSG结构指针。
  9. hWnd:其消息被检查的窗口句柄。
  10. wMsgFilterMin:指定被检查的消息范围里的第一个消息。
  11. wMsgFilterMax:指定被检查的消息范围里的最后一个消息。
  12. wRemoveMsg:确定消息如何被处理。此参数可取下列值之一:
  13. PM_NOREMOVE:PeekMessage处理后,消息不从队列里除掉。
  14. PM_REMOVE:PeekMessage处理后,消息从队列里除掉。
  15. 可将PM_NOYIELD随意组合到PM_NOREMOVE或PM_REMOVE。此标志使系统不释放等待调用程序空闲的线程。
  16. 缺省地,处理所有类型的消息。若只处理某些消息,指定一个或多个下列值:
  17. PM_QS_INPUT:Windows NT5.0和Windows 98:处理鼠标和键盘消息。
  18. PM_QS_PAINT:Windows NT 5.0和Windows 98:处理画图消息。
  19. PM_QS_POSTMESSAGE:Windows NT 5.0和Windows 98:处理所有被寄送的消息,包括计时器和热键。
  20. PM_QS_SENDMESSAGE:Windows NT 5.0和Windows 98:处理所有发送消息。
  21. 返回值:如果消息可得到,返回非零值;如果没有消息可得到,返回值是零。</span></span></span>

PeekMessage在检索应用程序的消息队列时,如果其中有消息就将其放入lpMsg(如下所示的函数原型的声明中)所指的结构中,同时PeekMessage函数不会等到有消息放入队列时才返回。同样,如果hWnd为NULL,则PeekMessage检索对象为进程的消息队列;如果hWnd = -1,那么函数只检索消息队列中hWnd参数为NULL的PostThreadMessage函数投递的消息;如果wMsgFilterMin和wMsgFilterMax都是0,则PeekMessage就检索所有有效消息;对一个消息在完成检索之后,可以显式地删除之(WM_PAINT例外,因为WM_PAINT需要合并处理,只有在合并处理之后才会被删除),也可以显式地保留之。

和函数GetMessage不一样的是,GetMessage:从系统获取消息,将消息从系统中移除,属于阻塞函数。当系统无消息时,GetMessage会等待下一条消息。而函数PeekMesssge是已查看的方式从系统中获取消息,可以不将消息从系统中移除,是非阻塞函数;当系统无消息时,返回FALSE,继续执行后续代码。

PeekMesssge只得到那些与参数hWnd标识的窗口相联系的消息或被lsChild确定为其子窗口相联系的消息,并且该消息要在由参数wMsgFiterMin和wMsgFiherMax确定的范围内。如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。如果hWnd为-1,PeekMessage只返回hWnd值为NULL的消息,该消息由函数PostThreadMessage寄送。如果wMsgFilterMin和wMsgFilterMax都为零,PeekMessage返回所有可得的消息(即,无范围过滤)。
[cpp]  view plain copy print ?
  1. <span style="font-family:Microsoft YaHei;"><span style="font-family:Courier New;"><span style="font-family:Comic Sans MS;font-size:14px;">while (GetMessage (&msg, NULL, 0, 0))
  2. {
  3. TranslateMessage (&msg) ;
  4. DispatchMessage (&msg) ;
  5. }
  6. return msg.wParam ;</span></span></span>

在MFC主进程中,如果计算量太大,会造成界面无响应,我们可以在循环中加入如下指令,方可解决。

[cpp]  view plain copy print ?
  1. <span style="font-family:Microsoft YaHei;"><span style="font-family:Courier New;"><span style="font-family:Comic Sans MS;font-size:14px;">while (TRUE)
  2. {
  3. if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
  4. {
  5. if (msg.message == WM_QUIT)
  6. break ;
  7. TranslateMessage (&msg) ;
  8. DispatchMessage (&msg) ;
  9. }
  10. else
  11. {
  12. // 完成某些工作的其它行程序
  13. }
  14. }
  15. return msg.wParam ;</span></span></span>

PeekMessage完美解决MFC主界面无响应相关推荐

  1. Ubuntu16.04 下的网易云出现网络异常、无法播放,界面无响应问题的统一解决

    能够在Linux系统下体验到原生界面的网易云音乐是件不错的事情,但是它总是经常性的出现网络异常,界面无响应的问题 为了听歌的体验,进行深入探究: 首先通过终端启用网易云音乐:sudo netease- ...

  2. python(pyqt5)多线程解决界面无响应

    多线程解决界面无响应多线程解决界面无响应多线程解决界面无响应 def open_train_task():import osos.system(r"E:\kg\TURN-TAP-master ...

  3. 关于如何解决Windows10任务栏无响应问题及任务栏“咨询和兴趣”功能入口彻底关闭

    关于如何解决Windows10任务栏无响应问题及任务栏"咨询和兴趣"功能入口彻底关闭 一.前言 二.过程 (1)资源管理器 (2)新的问题,新的发现 (3)锁定"咨询与兴 ...

  4. python PyQt5程序运行界面无响应

    写在前面 此文档仅记录本人遇到的问题及解决办法,并非涵盖所有 最近写一个股价监控小程序,在改进为界面程序后,每次运行到耗时方法时界面就卡死,无响应,花费了很长事件才把问题解决了,记录一下 原因分析 程 ...

  5. 进入qq空间显示服务器错误,解决QQ空间打开无响应或报错的方法

    QQ空间进入无响应或者报错(如下图)情况,请尝试以下解决方法: 一.建议清除IE缓存,了解清除IE缓存方法请点这里查看: 二.进入"工具"=>"Internet选项 ...

  6. 三种解决访达持续无响应的方法

    大家在使用Mac系统的时候是否遇到过Finder持续无响应,导致一系列操作无法实施的问题.这种情况通常出现在将Mac更新到了最新的macOS或者电脑使用太久,系统文件损毁之后,导致Finder突然出现 ...

  7. vs2008打开aspx设计界面无响应问题解决方法

    http://www.lzgame.com/html/blogview-7-244_1.html 突发问题,先是同事的VS2008在开发web项目时过5分钟就卡死,还被我嘲笑了一番...帮他整了一早上 ...

  8. Ubuntu 10.10 鼠标随机停顿及界面无响应问题解决方案

    纠正: 其实之前一直没有找到问题的真正原因,今天终于找到了,是因为Kworker占用CPU太多,是一个叫做drm_kms_helper的内核模块, 有一个功能叫做:DRM_KMS_POLLING 的功 ...

  9. 关于HP ILO 卡图形界面无响应的解决方案

    HP的远程管理卡叫ILO,是一套独立于服务器操作系统的单片机,用于服务器的远程管理. HP ILO在使用过程中,发现有些管理卡明明已经配置好了IP,但是图形界面无法打开,如果真碰上紧急的服务器维护情况 ...

最新文章

  1. Python map() 函数
  2. 【大前端之前后分离01】JS前端渲染VS服务器端渲染
  3. Windows Mobile使用Web Service上传和下载二进制数据流
  4. HDU 4023 (博弈 贪心 模拟) Game
  5. java品酒会,我学 rxjava 2(3)- 热发射
  6. cpu 抖动_微抖动,繁忙的等待和绑定CPU
  7. c语言连接mysql_聊聊数据库MySQL、SqlServer、Oracle的区别,哪个更适合你?
  8. linux gcc 示例_最好的Linux示例
  9. 微软拥抱开源_如何拥抱开源劳动力
  10. Python稳基修炼的经典案例12(计算机二级、初学者必会的字符文件处理)
  11. gstat | 空间插值(一)——反距离权重插值;使用ggplot2绘制地图
  12. android开发actionbar,Android 开发之为ActionBar 添加Actionbar Button
  13. ap sat_新手必读:7个问题分清SAT、AP、托福考试
  14. I2S和PCM区别(二十)
  15. Python让繁琐工作自动化——chapter16 发送电子邮件和短信
  16. glide源码中包含了那种设计模式_Glide源码解读(一)
  17. poedit使用(本地化和国际化)
  18. pigxCloud微服务项目04——服务端——腾讯云即时通信IM,拉取群历史消息(全量消息、所有群消息)
  19. 在小县城做什么赚钱?来看看这十种赚钱的项目吧!
  20. 在线编译器汇总|2020年最新版

热门文章

  1. 会计凭证合并OBCY
  2. vue 大小端,十六进制转十进制
  3. 移动硬盘无法访问“文件或目录损坏且无法读取”,怎样才能修复?
  4. 全球汽贸网汽车资讯:芯片相关的减产速度有所放缓
  5. 判断浏览器是否为IE6的两种方式
  6. 计算机缺少鼠标无法启动,鼠标故障大全集合!精选解决方法超详细!
  7. 约战精灵再临服务器维护,约战精灵再临进不了游戏怎么办_无法进入游戏解决方法...
  8. securecrt 6.1注册码
  9. 解决GridView控件的居中问题
  10. linux下ipvsadm命令,Linux命令:ipvsadm