首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

更安全的DoEvents函数解决思路

2012-03-22 
更安全的DoEvents函数C/C++ codeinline void DoEvents(){MSG msg //定义一个MSG类型的变量,不多解释while

更安全的DoEvents函数

C/C++ code
     inline void DoEvents(){        MSG msg; //定义一个MSG类型的变量,不多解释        while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //获取消息并把该消息从消息队列中移除(防止重复响应)。        {        DispatchMessage(&msg); //将消息移交给过程函数        TranslateMessage(&msg);//翻译消息 在合适的机会产生char消息        }     }


分析:DoEvents函数相当于是一个消息循环,可以在耗时运算里使用来解决假死的问题。

示例:
  我想延迟2秒弹出信息框:
C/C++ code
        Sleep(2000;)//延迟2秒        MessageBox("已经延迟2秒","信息:",MB_OK);


  这样一来,调用Sleep时窗口就会假死,为了在不引入多线程编程的前提下解决这个问题,那就可以使用 DoEvents函数来实现
C/C++ code
for (int i=1;i<=100;i++){Sleep (20);Doevent();}MessageBox("已经延迟2秒","信息:",MB_OK);


  代码分析,虽然在执行以上代码时窗口的消息循环函数会被堵塞,但是程序在每延迟20ms会进行一次检查并响应消息(将消息移交给过程函数处理),充当着一个消息循环的角色,窗口消息能获得及时的响应,程序自然不会假死,执行100次Sleep(20);就等价于Sleep(2000);。而DoEvents ();耗时可以忽略。

然而,以上代码有一个不足,那就是

C/C++ code
PeekMessage(&msg,NULL,0,0,PM_REMOVE)


的消息获取方式可能会接收到非窗体消息(其他线程消息),以下代码可以完美解决这个问题。


C/C++ code
#include "windows.h"BOOL CALLBACK EnumWindows1(HWND hwnd, LPARAM lParam);BOOL CALLBACK EnumWindows2(HWND hwnd, LPARAM lParam);void SafeDoevents ();//================================================================void SafeDoevents(){    EnumThreadWindows(GetCurrentThreadId(),EnumWindows1,0);};inline void DoWindowEvent(HWND m_hWnd){        MSG msg;    while(PeekMessage(&msg,m_hWnd,0,0,PM_REMOVE)) //获取消息并从消息队列中删除(防止重复响应)。    {        DispatchMessage(&msg); //将消息移交给过程函数        TranslateMessage(&msg);//翻译消息 在合适的机会产生char消息    }}BOOL CALLBACK EnumWindows1(HWND hwnd,LPARAM lParam){        DoWindowEvent(hwnd);    EnumChildWindows(hwnd,EnumWindows2,0);    return true;}BOOL CALLBACK EnumWindows2(HWND hwnd,LPARAM lParam){    DoWindowEvent(hwnd);    return true;}


[解决办法]
探讨
引用:

分享?


第一次在CSDN里发帖,不懂规矩,多多指教哦。

[解决办法]
TranslateMessage应该在DispatchMessage前面

热点排行