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

更保险的DoEvents函数

2013-04-20 
更安全的DoEvents函数inline void DoEvents(){MSG msg //定义一个MSG类型的变量,不多解释while(PeekMessa

更安全的DoEvents函数


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


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

示例:
        我想延迟2秒弹出信息框:

        Sleep(2000;)//延迟2秒
        MessageBox("已经延迟2秒","信息:",MB_OK);


        这样一来,调用Sleep时窗口就会假死,为了在不引入多线程编程的前提下解决这个问题,那就可以使用 DoEvents函数来实现

for (int i=1;i<=100;i++){
Sleep (20);
Doevent();
}
MessageBox("已经延迟2秒","信息:",MB_OK);


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

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

PeekMessage(&msg,NULL,0,0,PM_REMOVE)


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


#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前面

热点排行