duilib界面库消息流程分析

duilib 消息循环机制 1 消息处理 ​ 在duilib中我们一般会创建一个继承WindowImplBase的窗口,然后重写Notify函数,在Notify函数中处理控件消息,比如button的消息类型就是click,代码如下所示: class MyWnd :public DuiLib::WindowImplBase{ ... virtual void Notify(DuiLib::TNotifyUI& msg) override; }; void MyWnd::Notify(DuiLib::TNotif 阅读详情

对照duilib源码,主要看下CWindowWnd类与CPaintManagerUI类中对消息分发的处理。

1. CPaintManagerUI类的MessageLoop函数
void CPaintManagerUI::MessageLoop()  
{  
    MSG msg = { 0 };  
    while( ::GetMessage(&msg, NULL, 0, 0) ) {    //获取消息  
        if( !CPaintManagerUI::TranslateMessage(&msg) ) { //消息过滤  
            ::TranslateMessage(&msg);  
            ::DispatchMessage(&msg); //分发到窗口的消息处理窗口中. 也就是调用CWindowWnd类的__WndProc函数或是__ControlProc函数.  
        }  
    }  
}

消息第一次会由CPaintManagerUI类的TranslateMessage消息接收到.

2. 调用CWindowWnd::Create创建窗口

Create中主要完成以下操作:

  • 如果要子类下Window的控件(就是系统的控件, 而不是duilib的模拟控件), 就设置__ControlProc函数为消息回调函数.
  • 不子类化, 就注册窗口类. 此时设置__WndProc为窗口消息处理回调函数.
  • 用CreateWindowEx API函数创建窗口.

注:
__WndProc函数定义:

LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
    CWindowWnd* pThis = NULL;  
    if( uMsg == WM_NCCREATE ) { //要在此消息中把类于窗口进行绑定  
        LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); //来自于CreateWindowEx函数的最后一个参数( 也就是CWindowWnd对象指针了 )  
        pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams);  
        pThis->m_hWnd = hWnd;  
        ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(pThis)); //设置到窗口的用户数据中  
    }   
    else {  
        pThis = reinterpret_cast<CWindowWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));  
        if( uMsg == WM_NCDESTROY && pThis != NULL ) {  
            LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam);  //收到窗口能处理到的最后一个消息了, 要进行收尾工作了.  
            ::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L);  //取消类对象与窗口的绑定关系  
            if( pThis->m_bSubclassed ) pThis->Unsubclass();  
            pThis->m_hWnd = NULL;  
            pThis->OnFinalMessage(hWnd);  
            return lRes;  
        }  
    }  
    if( pThis != NULL ) {  
        return pThis->HandleMessage(uMsg, wParam, lParam);  //在此调用继承类的消息处理函数  
    }   
    else {  
        return ::DefWindowProc(hWnd, uMsg, wParam, lParam); //未绑定类对象, 就调用默认的窗口消息处理函数  
    }  
}

消息第二次就由__WndProc接收到, 然后再传到CWindowWnd类的HandlerMessage函数中.

3. CWindowWnd类的窗口继承类对于HandlerMessage虚函数的实现
LRESULT CMainWnd::HandleMessage( UINT uMsg, WPARAM wParam, LPARAM lParam )  
{  
    LRESULT lRes = 0;        //消息处理返回值.  
    BOOL    bHandled = TRUE; //消息是否要继续往下传.  
    switch ( uMsg )  
    {  
    case WM_CREATE: 
        lRes = OnInitResource( bHandled );  //进行初始化工作. 比如最重要的XML加载解析工作. 
        break;  
    default:  
        bHandled  = FALSE;  
        break;
    }  

    if ( bHandled )  
    {  
        return lRes;  
    }  

    //传给CPaintManagerUI::MessageHandler函数进行具体的控件处理工作  
    if ( m_pm.MessageHandler( uMsg, wParam, lParam, lRes ) )    
    {  
        return lRes;  
    }  

    //没处理过的就调用CWindowWnd类的默认消息处理函数吧. 
    return CWindowWnd::HandleMessage( uMsg, wParam, lParam );   
}

在这里就是用户要按消息进行具体的处理了. 之后要传到CPaintManagerUI类对象的MessageHandler函数. 未处理的消息就要返回给CWindowWnd类的默认消息处理函数来处理了.

4. CPaintManagerUI类的TranslateMessage, MessageHandler函数
BOOL CPaintManagerUI::TranslateMessage(const LPMSG pMsg)  
{  
    HWND hwndParent = ::GetParent(pMsg->hwnd); //获取消息接收窗口的父窗口  
    UINT uStyle = GetWindowStyle(pMsg->hwnd); //获取窗口的样式  
    LRESULT lRes = 0;  
    for( int i = 0; i < m_aPreMessages.GetSize(); i++ ) { //这个m_aPreMessage保存着CPaintManagerUI类对象.   
        CPaintManagerUI* pT = static_cast<CPaintManagerUI*>(m_aPreMessages[i]);  
        if( pMsg->hwnd == pT->GetPaintWindow() //消息是否属于当前CPaintManagerUI绑定的窗口  
         || (hwndParent == pT->GetPaintWindow() && ((uStyle & WS_CHILD) != 0)) ) //消息是否为当前窗口中窗口的消息, (如ActiveX控件 )  
        {  
            if( pT->PreMessageHandler(pMsg->message, pMsg->wParam, pMsg->lParam, lRes) ) return TRUE; //此时就调用PreMessageHandler过滤函数.  
        }  
    }  
    return FALSE;  
}

m_aPreMessage为静态成员变量, 在CPaintManagerUI::Init进行窗口与此类绑定时添加到此变量中.

5. CPaintManagerUI::PreMessageHandler消息过滤函数
BOOL CPaintManagerUI::PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& /*lRes*/)  
{  
    // 遍历当前的消息过滤列表. m_aPreMessageFilter的元素为IMessageFilterUI接口.只一个虚函数MessageHandler.   
    // 用户可以添加此接口的继承类变量到m_aPreMessageFilters列表中. ( 调用AddMessageFilter函数实现 )  
    for( int i = 0; i < m_aPreMessageFilters.GetSize(); i++ )   
    {  
        BOOL bHandled = FALSE;  
        LRESULT lResult = static_cast<IMessageFilterUI*>(m_aPreMessageFilters[i])->MessageHandler(uMsg, wParam, lParam, bHandled);  
        if( bHandled ) {  
            return TRUE;  
        }  
    }  
    // 以下是对几个按键消息的过滤.  
    // WM_KEYDOWN     检查是否为VK_TAB键, 要进行控件焦点的移动.  
    // WM_SYSCHAR     获取与wParam中的字符加速键匹配的控件, 并激活它.  
    // WM_SYSKEYDOWN  生成控件事件( 用TEventUI来模拟 )  
}
6. CPaintManagerUI::MessageHandler函数
  1. 遍历m_aMessageFilters列表中的IMessageFilterUI接口, 并调用MessageHandler函数, 再次进行相关的消息过滤功能.(与上面的m_aPreMessageFilters类似)

  2. 在此会处理窗口的WM_PAINT消息. 显示所有控件的外观与状态.

  3. 处理鼠标事件, 实现控件激活和相关事件.

  4. 处理WM_TIMER消息, 所有控件要用CPaintManagerUI的SetTimer, KillTimer等函数实现计时器功能.

  5. 处理CPaintManagerUI类的自定消息, WM_APP + 1与 +2,
    WM_APP + 1是用于控件延迟销毁控件对象
    WM_APP + 2销毁异步消息的处理.
    ( 异步控件消息用CPaintManagerUI::SendNotify函数, 把消息对象添加到m_aAsyncNotify列表中, 再PostMessage函数WM_APP + 2 )

  6. 其它基本的窗口相关消息的处理.
    CPaintManagerUI把DUILIB内部的事件都是用TEventUI结构的形式调用CControlUI类的Event函数来投递的.

初识Duilib界面库 国内首个开源 的directui 界面库,开放,共享,惠众,共赢,遵循bsd协议,可以免费用于商业项目,目前支持Windows 32 、Window CE、Mobile等平台。Duilib 是一款强大的界面开发工具,可以将用户界面和处理逻辑彻底分离,极大地提高用户界面的开发效率。提供所见即所得的开发工具UIDesigner。使用DirectUI后将使得我们的设计人员彻底解 放,不会受到开发的束缚,可 阅读详情

相关推荐

duilib消息类型汇总

自定义消息是应用程序开发者自己定义的消息类型,用于在不同的控件之间进行通信和传递数据。这些消息通常不是系统定义的消息,而是开发者根据自己的需求添加的。自定义消息的用途包括但不限于在控件之间传递数据、触发特定的操作等。当控件接收到自定义消息时,它会调用对应的处理函数来处理这些消息。事件消息是在DuiLib中预定义的消息类型,用于响应用户的交互操作,如鼠标点击、键盘输入等。当用户在控件上进行操作时,DuiLib会生成相应的事件消息,并传递给控件的父控件,直到找到一个处理该事件的控件为止。

森明帮大于黑虎帮的博客 1283

duilib 窗口,对话框

主窗口显示 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow) { _CrtDumpMemoryLeaks(); // COM HRESULT Hr = ::CoInitialize(NULL); if( FAILED(Hr) ...

qq_24127015的博客 1176

Duilib--->Duilib库介绍&总结&概述

DuiLib库 介绍: DuiLib(第三方库,应用窗口美化,逻辑操作与界面分离,用XML文档进行界面编辑)(DUI与GUI/VUI的对比) 概念与定义: DuiLib库是轻量级的C++界面开发库。duilib并没有像MFC那样把所有的东西全包了,它仅仅包装了UI部分而已,其他的还是需要用win32、MFC的知识,所以除了UI部分,其他的都和duilib没有关系。 逻辑操作与界面分离了。 DuiLib库优点与缺陷: 优点: 基于GDI在窗口上自绘,无其他依赖,未使用特殊或危险的系统调用,能够很好的解决传统

qq_42069216的博客 4225

DUILib学习笔记---消息处理

WIN32下窗口消息循环 MSG msg = { 0 }; while( ::GetMessage(&msg, NULL, 0, 0) ) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } 1.消息循环,在CPaintManagerUI::MessageLoop() --------duilib中增加了一个消

jadeshu的博客 781

使用DuiLib进行UI开发的虚函数解析及控件绑定、响应与消息处理

在DuiLib中,界面的布局和控件通常通过XML文件来定义。以下是一个简单的XML文件示例,该文件定义了一个带有按钮和标签的布局:<Button name="btnOK" text="确定" /><Label name="lblStatus" text="状态" /></Window>1.定义控件变量public:// 其他函数和成员变量2.在Init函数中绑定控件有时我们需要处理一些自定义的消息,例如计时器消息或DPI改变消息。// 处理计时器消息// 处理DPI改变消息。

吃面不喝汤的博客 1339

Duilib扩展—双击、右键消息扩展

用过duilib的可能会发现,duilib中有些控件没能很好的区分左键、右键等消息。所以根据实际需要,我们需要进行相关区分处理,或者自行扩展。 一. 左键、右键消息区分 我们以CListUI控件来分析说明。对于CListUI控件,在实际应用中有时我们需要响应双击或右键消息来执行不同操作,而目前的duilib中CListUI控件Item选择是无法区分左键右键消息的,究其原因duilib中对这

7-SEVENS 4198

duilib虚拟窗口使用

 方便每一个TabLayout的界面都可以用一个类去处理;避免将所有的消息写到同一个主窗口类中;方便维护;主窗口代码:构造函数中添加CEtcdMainWnd::CEtcdMainWnd() { AddVirtualWnd(_T("PatManage"),&amp;m_PatManagePage); //加载“病例管理”界面 PatManage与xml配置必须相同 m_Pat...

C2018的博客 2061

C++开源界面库Duilib框架与内部实现机制详解

C++开源界面库Duilib框架与内部实现机制详解

dvlinker的技术专栏 1263

DUILIB创建不规则窗体

声明:原始方法部分已经废弃,现在有更好的办法来实现DUILIB加载PNG图片,为保持学习的渐进性,我还是保留了原始方法部分的博文与代码,大家没有必要看原始部分了,直接看新方法部分吧; 新方法 前言:上周我研究了一周如何在DUILIB中加载PNG不规则背景图,但毕竟还是新接触GDI绘图,难度还是挺大的,一直没能找到一种方法在DUILIB中不大规模修改代码的情况下,能实现PNG图片加载,正

启舰 1万+

别再手动填序号了!用Python脚本在Arcgis属性表里实现分组自动编号(附完整代码)

本文详细介绍了如何利用Python脚本在Arcgis属性表中实现分组自动编号,告别低效的手工操作。通过核心代码解析和实战教程,帮助GIS工程师快速掌握自动化编号技术,提升工作效率并降低错误率。特别适合城市规划、国土调查等需要处理大量分组数据的场景。

weixin_42532473的博客 306

配置VScode编译、调试STM32(一)手动配置makefile和debug

做嵌入式的朋友们都应该有过想要有个功能强大的IDE或者编辑器,Keil MDK5、IAR EWARM是用的比较普遍的平台了,但是两者在编辑器方面都比较弱势,当然可以设置 或者使用外部编辑器,像Sourceinsight、notePad++这样,但毕竟需要切换回来进行Build、Debug,非常麻烦。 VScode从发布至今口碑一直很好,而且里面有非常多的插件,比如彩虹括号、Code Runner、...

hanhe0551的博客 4289

Duilib源码分析(一)整体框架

  Duilib界面库是一款由杭州月牙儿网络技术有限公司开发的界面开源库,以viksoe项目下的UiLib库的基础上开发(此后也将对UiLib库进行源码分析);通过XML布局界面,将用户界面和处理逻辑彻底分离,极大地提高用户界面的开发效率。一般常用于开发小型项目Windows桌面客户端软件;其子窗口不以窗口句柄的形式创建,只是逻辑上的窗口,绘制在父窗口之上。目前开源协议以BSD发布,可使...

diansiji9321的博客 721

python基于语音识别的智能垃圾分类系统

大家好我是蓝天,混迹在java圈的辛苦码农。今天要和大家聊的是一款《python基于语音识别的智能垃圾分类系统》毕业设计项目。项目源码以及部署相关请联系蓝天,文末附上联系信息。🎈作者:蓝天🎈🎈个人简介:精通 Java、Python、C#、C、C++ 等编程语言,同时对微信小程序、Php 和 Android 等技术也能熟练掌握,可为大家提供全面的技术支持与交流。我拥有丰富的成品 Java、Python、C# 毕业设计项目经验,能够为学生提供各类个性化的开题框架及实际运作方案。🎈。

Chujun123528的博客 660

DuiLib简介

duilib库是一款轻量级的C++界面开发库,遵循开源BSD协议,可以免费用于商业项目,由杭州月牙儿网络技术有限公司开发。duilib库的源码下载地址:https://github.com/duilib/duilib。 传统MFC界面库有如下问题: 1) 不美观 2) 界面细节处理不好 3) 使用硬编码 4) 开发效率低下 5) 生成程序体...

Best_ZYJ的博客 1万+

手把手教你学Simulink——基于经典PID控制的电机系统场景实例:BLDC电机PID电流控制策略仿真

*无刷直流电机(Brushless DC Motor, BLDC)**因其高效率、长寿命和低维护成本,在众多领域如家用电器、工业自动化、电动汽车等得到了广泛应用。为了实现对BLDC电机的有效控制,通常采用基于霍尔传感器或反电动势检测的换相技术,并结合电流闭环控制以提高系统的动态响应和稳定性。本教程将带你使用构建一个基于PID控制的BLDC电机电流控制策略仿真模型BLDC电机建模PID控制器设计与应用系统仿真与调试控制效果分析本文介绍了如何使用构建一个。

MHD0815的博客 196

Android11车机系统海外项目资源包RRO方案优化

本文介绍了汽车设置应用如何通过Android RRO(运行时资源叠加)方案实现多车型差异化资源管理。针对不同车型(国内/海外、轿车/SUV)和配置(方向盘、轮毂等),采用产品变体(productFlavors)构建不同APK版本,并通过JSON配置文件动态启用对应资源包。系统根据车辆下线配置自动匹配适用的资源叠加包,解决了硬编码判断带来的维护问题。该方案实现了资源的高效复用,同时支持灵活配置多种车型组合,为汽车行业多车型共平台开发提供了可扩展的技术实现。

shusuanly的博客 469

Windows C++界面库

记得大一学C语言的时候,觉得黑白窗很无聊,后来在网上找到了EasyX (一个模仿turbo c的图形库)http://www.easyx.cn ,用它写一些贪吃蛇、扫雷这类有图形界面的游戏来练手。 当时学的时候就很好奇为什么调用这些函数就能绘制图形,后来从网上了解到了Windows编程,于是从淘宝淘了本《Windows程序设计》看了起来,当时看的时候还有点吃力。 趁着大一结束后的那次暑假我看完了王

优快云文章已停止维护,后续文章会在 https://blog.hufeifei.cn 持续更新 1万+

Oracle EBS 中美国销售税的实现方式

Oracle EBS通过eBTax引擎实现美国销售税管理,需配置税务管辖区、税率及规则等要素,基于收货地址和商品分类计税。系统支持免税交易和使用税处理,但因美国税率复杂多变,建议集成Vertex等第三方服务自动更新税率。关键配置包括创建USSales Tax制度、维护地点层级及物料税务分类,同时需管理客户免税证书。对于跨国业务,系统也支持欧盟VAT等其他国家税制配置。

金牌架构师 295

duilib介绍-1

关于duilib的介绍就不多讲了,一来不熟,二来小伙伴们想必已经对比了多个界面库,也无需赘述。下面进入正题: 不看广告看疗效! 已有众多知名公司采用duilib做为界面库,如华为网盘、PPS(PPS和华为之前都是用UIPower)、金山快盘(也没用自家的界面库)、酷我音乐、爱奇艺视频、百度杀毒、百度卫士、百度管家等一系列产品。而duilib自己提供的Demo有QQ、QQ旋风、360等等。下面是一部分截图: 这么好的东东,都开源三年多了,肿么一直没有个像样的文档和入...

顺其自然~专栏 7453

Ardupilot二次开发(二):自定义mavlivk消息

在下面的文件添加自定义消息的xml定义然后编译固件,会生成相应的消息头文件。

超维空间科技的博客 2312

华为OD机试真题2025双机位A卷 Python&JavaScript 实现【采购订单】

在一个采购系统中,采购申请(PR)需要经过审批后才能生成采购订单(PO)。每个PR包含商品的单价(假设相同商品的单价一定是一样的)及数量信息。系统要求对商品进行分类处理:单价高于100元的商品需要单独处理,单价低于或等于100元的相同商品可以合并到同一采购订单PO中。针对单价低于100的小额订单,如果量大可以打折购买。

MISAYAONE的博客 1455

C++图形界面库之Duilib

Duilib 是一个强大的、开源的 Windows 平台下的 DirectUI 界面库。Duilib 是一个让你能用 C++ 和 XML 文件来高效开发出漂亮、自定义程度高的 Windows 桌面客户端软件的开发框架。​。

hdjsjb的博客 2601

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Duilib界面库文档详解:从官方Wiki到源码注释解读

Duilib作为Windows平台下的DirectUI界面库,采用分层架构设计,核心模块包括基础定义层、渲染引擎层、控件系统层和布局管理层。以下是基于源码分析的架构总览: ```mermaid classDiagram direction BT class Core { + UIDefine.h : 基础类型定义 + UIManager.h : 界...

gitblog_00142的博客 1261

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

nim_duilib界面库快速上手(Windows系统,VS 2022)

本文介绍了如何在Windows系统下使用VS 2022快速部署基于nim_duilib界面的应用程序。主要内容包括:获取并编译nim_duilib和skia源码、创建基础工程、配置项目属性、引入线程库以及创建一个简单窗口。文章提供了详细的步骤指导,包括代码示例和配置说明,帮助开发者快速上手使用nim_duilib界面库。重点介绍了项目结构设置、资源引用、主线程实现和窗口创建等关键环节,并附有相关截图说明,便于开发者理解和操作。

m0_51545131的博客 1067

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

duilib消息类型

duilib作为一个轻量快速的开源界面库,有很多值得学习的地方,虽然也有不少人吐槽它的各种问题,但是它是一种技术,技术没有正确与错误,好与坏之分,可以取其精华,学为己用就足够了。 本篇记录duilib的消息类型(类似于MFC的消息)。 消息 说明 Sender 宏定义 link CTextUI、CListTextElementUI DUI_MS...

积累点滴,保持自我 1266

终极Duilib指南:为什么这款Windows界面库能让你的开发效率提升300%?

Duilib不仅仅是一个界面库,更是一种开发理念的革新。它通过XML驱动、硬件加速、模块化设计等先进理念,让Windows界面开发变得更加简单、高效和有趣。 无论你是刚入门的新手,还是经验丰富的开发者,Duilib都能为你带来显著的效率提升。从今天开始,告别繁琐的界面代码,拥抱Duilib带来的开发新体验! **如果你觉得这篇文章对你有帮助,请点赞、收藏、关注三连!** 我们下期将深入解析Du

gitblog_00918的博客 771
上一篇: Duilib学习笔记《07》— 资源加载
下一篇: C/C++const用法
7-sevens
博客等级 码龄10年 259粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值