windows 消息队列,消息循环,模态对话框

Windows的消息队列是基于线程的。


消息队列,消息循环:

线程是程序串行执行的最小单位。

一个典型的Win32项目(不是MFC项目,只有一个窗口的项目),其中的消息循环会使用如下代码实现:


//代码段1

MSG msg

BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)

    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

GetMessage()是取得消息,如果没有消息,线程阻塞在这里,不占用CPU。

DispatchMessage()是将消息分发,分发到所有在这个线程中创建的窗口的窗口处理函数中去。 如果不需要分发消息,就不需要调用DispatchMessage(),例如线程中没有窗口的情况。


线程消息循环:

实际上,任何线程只要调用了上述代码段1中的代码,就已经实现了消息循环的功能。更进一步,其实只要调用GetMessage()函数就可以了。

即:

//代码段2

BOOL bRet;  MSG msg;
while( (bRet = GetMessage(&msg, NULL, 0, 0)) != 0)

if (bRet == -1 || WM_QUIT == msg.message){
// handle the error and possibly exit
break;
}

        }

在工作线程中,只要有代码段2,就可以实现消息循环的功能了。

这是一个很方便的线程间异步通信的机制。给线程发消息用PostThreadMessage()。为什么去掉了DispatchMessage()呢,因为一般情况下,在工作线程中是不需要创建窗口的,不需要分发到窗口中去处理,能从线程的消息队列里取得消息就足够了。

如果设计线程的初衷为:当某条件发生时,让工作线程开始工作,一直将工作完成,之后挂起,等待新条件的发生,等待时不占用CPU资源。 那么代码段2所展示的机制就能很好的完成这样的功能。 而且可以使多个工作线程都用同样的机制实现,彼此间协同工作,加之某种资源共享机制,可以实现一个异步的消息处理链。


模态对话框:

消息循环可以有多个,可以在上一级消息循环的某个消息的处理过程中,局部创建一个消息循环,模态对话框就是采用这种机制创建出来的。

一个线程可以有多个消息循环,并行的消息循环显然没有意义,多个就是在消息循环中嵌套消息循环。

如代码段1中的DispatchMessage函数,将消息派发到窗口的消息处理函数中,WndProc1()。

现在假设在WndProc1()中创建一个消息循环,并且只取得这个窗口本身的消息 GetMessage(&msg, hWnd, 0, 0),不必Dispatch了,因为已经找到了目标窗口,然后用这个窗口真正的消息处理函数去处理。 这样模态对话框存在时,处理了所有的窗口消息,创建模态对话框的窗口就一直得不到处理消息的机会,模块对话框就始终处于最上层,直到其主动退出。

当然,对模态对话框的这种解释是简化了的,实际过程可能复杂的多,取得的窗口消息至少要包含所有的子窗口的消息,也需要Dispatch到相应的子窗口,等等。但是最基本的机制应该就是这样的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值