DuiLib消息处理剖析

转载链接:DuiLib消息处理剖析_赵克立博客_技术栈

DuiLib核心的大体结构图如下:

分为几个大部分:

  1. 控件

  2. 容器(本质也是控件)

  3. UI构建解析器(XML解析)

  4. 窗体管理器(消息循环,消息映射,消息处理,窗口管理等)

  5. 渲染引擎

DuiLib 消息循环剖析

DuiLib的消息循环非常灵活,但不熟悉的可能会觉得非常混乱,不知道该如何下手。所以,我总结了下DuiLib的各种消息响应的方式,帮助大家理解DuiLib和加快开发速度。

其消息处理架构较为灵活,基本上在消息能过滤到的地方,都给出了扩展接口。

看了DuiLib入门教程后,对消息机制的处理有些模糊,为了屏蔽Esc按键,都花了大半天的时间。究其原因,是因为对DuiLib消息过滤不了解。
你至少应该看过上面提及的那篇入门教程,看过一些DuiLib的代码,但可能没看懂,那么这篇文章会给你指点迷津。

Win32消息路由如下:

  1. 消息产生。

  2. 系统将消息排列到其应该排放的线程消息队列中。

  3. 线程中的消息循环调用GetMessage(or PeekMessage)获取消息。

  4. 传送消息TranslateMessage and DispatchMessage to 窗口过程(Windows procedure)。

  5. 在窗口过程里进行消息处理

我们看到消息经过几个步骤,DuiLib架构可以让你在某些步骤间进行消息过滤。首先,第1、2和3步骤,DuiLib并不关心。DuiLib对消息处理集中在CPaintManagerUI类中(也就是上面提到的窗体管理器)。DuiLib在发送到窗口过程的前和后都进行了消息过滤。

DuiLib的消息渠,也就是所谓的消息循环在CPaintManagerUI::MessageLoop()或者CWindowWnd::ShowModal()中实现。俩套代码的核心基本一致,以MessageLoop为例:

void CPaintManagerUI::MessageLoop()
{
    MSG msg = { 0 };
    while( ::GetMessage(&msg, NULL, 0, 0) ) {
        // CPaintManagerUI::TranslateMessage进行消息过滤
        if( !CPaintManagerUI::TranslateMessage(&msg) ) {
            ::TranslateMessage(&msg);
            try{
            ::DispatchMessage(&msg);
            } catch(...) {
                DUITRACE(_T("EXCEPTION: %s(%d)\n"), __FILET__, __LINE__);
                #ifdef _DEBUG
                throw "CPaintManagerUI::MessageLoop";
                #endif
            }
        }
    }
}

3和4之间,DuiLib调用CPaintManagerUI::TranslateMessage做了过滤,类似MFC的PreTranlateMessage

想象一下,如果不使用这套消息循环代码,我们如何能做到在消息发送到窗口过程前进行常规过滤(Hook等拦截技术除外)?答案肯定是做不到。因为那段循环 代码你是无法控制的。CPaintManagerUI::TranslateMessage将无法被调用,所以,可以看到DuiLib中几乎所有的 demo在创建玩消息后,都调用了这俩个消息循环函数。下面是TranslateMessage代码:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值