一.Duilib开发之基本使用

一. Duilib介绍

Duilib是一款轻量级,遵循BSD协议的开源C++ GUI框架,可以免费用于商业项目,是由杭州月牙儿网络技术有限公司基于DirectUI界面思想设计出来的GUI开源框架;所谓的DirectUI思想其实指的就是窗口只有一个,而窗体上面的所有东西(控件)都是绘制上去的(逻辑窗体,并不是真正意义上面的窗体控件,它是没有句柄的),而传统GUI程序,你所看到的任何一个控件其实本质都是一个窗体,只不过做成了某种功能控件(有句柄的),也就是所见一切皆窗体!

二. Duilib配置

1. Duilib版本下载

Duilib原版版本: https://github.com/duilib/duilib.//原版的
Duilib旗舰版本: https://gitee.com/qdtroy/DuiLib_Ultimate.//群维护
网易版,腾讯版等…

2. Duilib目录结构

//以Duilib原版版本作为介绍
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. Duilib源码编译

  1. 打开.sln解决方案:直接编译Duilib,QQDemo!
  2. Duilib解决方案下:bin目录找到QQDemo_d.exe运行就可以看到效果!

三. Duilib使用

1. 创建空解决方案

创建一个空的vs2013解决方案,在解决方案下创建一个Reference目录,这个目录就专门用来存放第三方库!

2. 加入Duilib工程

将Duilib工程放进去,打开解决方案,添加现有项目Duilib工程,配置并编译!

3. 静态编译Duilib

在这里插入图片描述
在这里插入图片描述

4. 简单-使用Duilib

  1. 创建Win32项目(删除多余代码 留空main函数)
// DuilibDemo.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "DuilibDemo.h"int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR    lpCmdLine,_In_ int       nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);return 0;
}
  1. 引用Duilib头文件所在目录/库文件所在目录
    在这里插入图片描述
    在这里插入图片描述
  2. 创建Duilib Win32 窗体!
    //CWindowWnd其实就是Duilib对纯Win32窗体的封装,创建Win32窗体,不支持Duilib界面特性(它可不认识和支持什么XML加载界面)!
#pragma once#include "UIlib.h"#ifdef _DEBUG
#pragma comment(lib,"Duilib_d.lib")
#else
#pragma comment(lib,"Duilib.lib")
#endifusing namespace DuiLib;class CDuilibWin32Wnd :public CWindowWnd
{
public:CDuilibWin32Wnd();~CDuilibWin32Wnd();protected:virtual LPCTSTR GetWindowClassName() const = 0;
};
#include "stdafx.h"
#include "DuilibWin32Wnd.h"CDuilibWin32Wnd::CDuilibWin32Wnd()
{
}CDuilibWin32Wnd::~CDuilibWin32Wnd()
{
}LPCTSTR CDuilibWin32Wnd::GetWindowClassName() const
{return L"DuilibWin32Window";
}
// DuilibDemo.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "DuilibDemo.h"
#include "DuilibWin32Wnd.h"int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR    lpCmdLine,_In_ int       nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);::CoInitialize(NULL);CPaintManagerUI::SetInstance(hInstance);//Duilib win32 窗体:CDuilibWin32Wnd duilibWin32Wnd;HWND hDuiWin32Wnd = duilibWin32Wnd.Create(NULL, L"DuilibWin32Wnd", WS_OVERLAPPEDWINDOW, NULL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL);if (hDuiWin32Wnd == NULL){MessageBox(NULL, L"DuilibWin32窗体创建失败!", L"Err", MB_OK);return false;}duilibWin32Wnd.CenterWindow();duilibWin32Wnd.ShowWindow(SW_SHOW);CPaintManagerUI::MessageLoop();::CoUninitialize();return 0;
}
  1. 创建Duilib 支持XML 窗体
    //WindowImplBase是Duilib在纯Win32窗体类的基础上融入Duilib特性(支持XML加载界面),给我们实现的一个支持Duilib特性的窗体类!(这样的一个Duilib窗体类,我们完全是可以自己写的)
    exe运行目录:创建skin目录,书写XML界面文件(demo.xml)
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Window size="668,469" caption="0,0,0,56" roundcorner="4,4"><Font id="0" name="微软雅黑" size="12"/><Font id="1" name="微软雅黑" size="14"/><Font id="2" name="微软雅黑" size="16"/><Font id="3" name="微软雅黑" size="18"/><VerticalLayout bkcolor="#FFFFFFFF"><HorizontalLayout name="ListContainer" vscrollbar="true" ><List name="list_data"><ListContainerElement pos="0,0,400,30" minheight="30" maxheight="30" mouse="true" mousechild="true" bordersize="1"><HorizontalLayout><HorizontalLayout><VerticalLayout><Control /><Button name="sectionNameBtn" height="20" text="button" align="left" textcolor="#FF0000FF" font="4" padding="20,0,0,0" focusedtextcolor="#FF00FF00" pushedtextcolor="#FFFF0000" /><Control /></VerticalLayout></HorizontalLayout><HorizontalLayout width="120"><Label name="DurationLabel" text="label" align="center" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />            </HorizontalLayout><HorizontalLayout width="60">				<VerticalLayout><Control /><Button name="playSectionBtn" text="play" align="center" width="50" height="20" font="1" bkcolor="#FF0090F0" textcolor="#FFFFFFFF"/><Control /></VerticalLayout></HorizontalLayout></HorizontalLayout>	</ListContainerElement>				</List></HorizontalLayout></VerticalLayout>
</Window>
#pragma once#include "UIlib.h"#ifdef _DEBUG
#pragma comment(lib,"Duilib_d.lib")
#else
#pragma comment(lib,"Duilib.lib")
#endifusing namespace DuiLib;class CDuilibXMLWnd : public WindowImplBase
{
public:CDuilibXMLWnd();~CDuilibXMLWnd();protected:virtual CDuiString GetSkinFolder();virtual CDuiString GetSkinFile();virtual LPCTSTR GetWindowClassName(void) const;
};
#include "stdafx.h"
#include "DuilibXMLWnd.h"CDuilibXMLWnd::CDuilibXMLWnd()
{
}CDuilibXMLWnd::~CDuilibXMLWnd()
{
}CDuiString CDuilibXMLWnd::GetSkinFolder()
{return L"./skin";
}CDuiString CDuilibXMLWnd::GetSkinFile()
{return L"Demo.xml";
}LPCTSTR CDuilibXMLWnd::GetWindowClassName(void) const
{return L"DuilibXMLWindow";
}
// DuilibDemo.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "DuilibDemo.h"
#include "DuilibWin32Wnd.h"
#include "DuilibXMLWnd.h"int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR    lpCmdLine,_In_ int       nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);::CoInitialize(NULL);CPaintManagerUI::SetInstance(hInstance);//Duilib win32 窗体://CDuilibWin32Wnd duilibWin32Wnd;//HWND hDuiWin32Wnd = duilibWin32Wnd.Create(NULL, L"DuilibWin32Wnd", WS_OVERLAPPEDWINDOW, NULL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL);//if (hDuiWin32Wnd == NULL)//{//	MessageBox(NULL, L"DuilibWin32窗体创建失败!", L"Err", MB_OK);//	return false;//}//duilibWin32Wnd.CenterWindow();//duilibWin32Wnd.ShowWindow(SW_SHOW);CDuilibXMLWnd duilibXMLWnd;HWND hDuiXMLWnd = duilibXMLWnd.Create(NULL, L"DuilibXMLWnd", WS_OVERLAPPEDWINDOW, NULL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL);if (hDuiXMLWnd == NULL){MessageBox(NULL, L"DuilibXMLWnd窗体创建失败!", L"Err", MB_OK);return false;}duilibXMLWnd.CenterWindow();duilibXMLWnd.ShowWindow(SW_SHOW);CPaintManagerUI::MessageLoop();::CoUninitialize();return 0;
}
  1. 实现Duilib 如何从原生Win32窗体(CWindowWnd)演变成支持Duilib特性(实现:WindowImplBase)的Duilib窗体!
//.h
//1.继承CWindowWnd 重写GetWindowClassName纯虚函数
class CBaseDuilibWnd :public CWindowWnd
{
public:CBaseDuilibWnd();~CBaseDuilibWnd();
protected:	virtual LPCTSTR GetWindowClassName() const;
private://创建Duilib UI管理器CPaintManagerUI m_pUI;
};
//2.重写HandleMessage 接收处理窗口过程消息
class CBaseDuilibWnd :public CWindowWnd
{
public:CBaseDuilibWnd();~CBaseDuilibWnd();//
protected:	virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);//处理消息virtual LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);virtual LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);virtual LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);//virtual LPCTSTR GetWindowClassName() const;
private:CPaintManagerUI m_pUI;
};
//.cpp
LRESULT CBaseDuilibWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{LRESULT lRes = 0;BOOL bHandled = TRUE;switch (uMsg){//创建窗体case WM_CREATE:lRes = OnCreate(uMsg, wParam, lParam, bHandled);break;//销毁窗体case WM_DESTROY:PostQuitMessage(0);break;default:bHandled = FALSE;}if (bHandled){return lRes;}//消息流向Duilib消息处理if (m_pUI.MessageHandler(uMsg, wParam, lParam, lRes))return lRes;//消息流向系统默认处理return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
}
...
//处理窗体创建消息WM_CREATE:
LRESULT CBaseDuilibWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{//窗体句柄给UI管理器m_pUI.Init(m_hWnd);//创建XML解析器CDialogBuilder builder;//解析并返回根UI节点CControlUI* pRoot = builder.Create(_T("Demo.xml"), (UINT)0, NULL, &m_pUI);ASSERT(pRoot && "Failed to parse XML");//将根节点加入UI管理器m_pUI.AttachDialog(pRoot);return 0;
}
#include "stdafx.h"
#include "DuilibDemo.h"
#include "BaseDuilibWnd.h"int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR    lpCmdLine,_In_ int       nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);//Duilib用到了COM所以需要进行COM初始化和销毁::CoInitialize(NULL);CPaintManagerUI::SetInstance(hInstance);/*custom XML Duilib 窗体*///设置资源路径 自己手写Duilib窗体类 skin放DuilibDemo工程目录或者将运行目录设置为exe所在目录DuiLib::CPaintManagerUI::SetResourcePath(TEXT("./skin"));CBaseDuilibWnd duilibBaseWnd;HWND hDuiXMLWnd = duilibBaseWnd.Create(NULL, L"DuilibBaseWnd", WS_OVERLAPPEDWINDOW, NULL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL);if (hDuiXMLWnd == NULL){MessageBox(NULL, L"DuilibBaseWnd窗体创建失败!", L"Err", MB_OK);return false;}duilibBaseWnd.CenterWindow();duilibBaseWnd.ShowWindow(SW_SHOW);//Duilib消息循环CPaintManagerUI::MessageLoop();::CoUninitialize();return 0;
}
所以,从上面我们自定义和实现支持Duilib特性窗体我们可以看出,主要重写窗口过程函数接收窗口消息处理,在创建窗体时,解析XML,Duilib接管窗口句柄和根UI元素节点,消息流向Duilib消息处理等一系列操作,设置资源路径就可以实现一个支持Duilib XML描述和渲染窗体的特性!
  1. 接收Duilib事件消息
//继承INotifyUI类,重写Notify接口
class CBaseDuilibWnd :public CWindowWnd,public INotifyUI
virtual void Notify(TNotifyUI& msg);
void CBaseDuilibWnd::Notify(TNotifyUI& msg)
{if (msg.sType == TEXT("windowinit")){OnInitWindow();}else if (msg.sType == TEXT("click")){CDuiString strName = msg.pSender->GetName();strName += L" click";MessageBox(NULL, strName, L"Info", NULL);}
}
//在窗体创建时(WM_CREATE)将当前窗体对象加入到Duilib事件通知里
m_pmUI.AddNotifier(this);

总结:通过上述流程,我们就可以掌握纯粹利用Duilib创建Win32窗体,Duilib特性窗体!

作者: 祁莫问.

下一篇: 二.Duilib开发之消息系统.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/60295.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

​阿里最新年报:万霖、蒋凡成合伙人;Twitter 网址迁移至 X.com;Cython 3.0 发布|极客头条...

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&#…

人工智能、ChatGPT及搜索引擎

搜索引擎通过收集互联网信息以及对这些信息的分析、索引、排序来为用户提供精准的搜索结果。人工智能则是实现和模拟人类智能的科学&#xff0c;包括图像识别、自然语言处理、机器学习等技术。在搜索引擎的应用中&#xff0c;人工智能技术可以被用于提升搜索结果的相关性、精准…

2023年电工杯B题半成品论文使用讲解

注&#xff1a;蓝色字体为说明备注解释字体&#xff0c;不能出现在大家的论文里。黑色字体为论文部分&#xff0c;大家可以根据红色字体的注记进行摘抄。该文件为半成品论文&#xff0c;即引导大家每一步做什么&#xff0c;怎么做&#xff0c;展示按着本团队的解题思路进行建模…

100天精通Python(可视化篇)——第96天:Pyecharts绘制多种炫酷箱形图参数说明+代码实战

文章目录 专栏导读1. 箱形图介绍1&#xff09;箱形图介绍2&#xff09;怎么看箱型图&#xff1f;3&#xff09;解释说明 2. 普通箱型图3. 水平箱型图4. 群组箱型图5. 带异常点的箱型图书籍推荐 专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到就业…

SAM(Segment Anything Model)让CV走到尽头?学CV的研究生还能正常毕业吗?怎么使用SAM?

SAM&#xff08;Segment Anything Model&#xff09;让CV走到尽头&#xff1f;学CV的研究生还能正常毕业吗&#xff1f;怎么使用SAM&#xff1f; 1. 引言 最近无论是在B站、知乎还是论坛、微博&#xff0c;都看了一些有关SAM的讨论。这个号称“CV界ChatGPT”的模型从出生起就…

GPT-4变笨实锤!3个月性能暴减1/10,代码生成大不如前,斯坦福最新研究引爆舆论

【导读】GPT-4性能下降终于有了依据。 GPT-4变笨实锤了&#xff1f; 斯坦福、UC伯克利最新研究称&#xff0c;和3月相比&#xff0c;GPT-4在6月的性能直接暴降。 甚至&#xff0c;代码生成、问题回答大不如前。 论文地址&#xff1a;https://arxiv.org/pdf/2307.09009.pdf …

留学文书why school怎么写你清楚吗?

每一个学校都期望你回答「为什么我要读你们这所学校」&#xff0c;有些学校将其成为一个问题&#xff0c;有些学校则内嵌在其他类型文书的小问题里。 然而&#xff0c;我们要记得&#xff0c;即使学校没有说要写&#xff0c;why school文书仍然是整个留学文书中不可或缺的一部分…

跨境电商平台开源BeikeShop系统-新增插件市场

前言&#xff1a;这次我们从v1.1.2升级到v1.2.0——BeikeShop终于迎来了一次大的变动&#xff01; 最重要的&#xff01;我们上线了beikeshop插件市场&#xff0c;用户可以根据需要付费购买、下载、上传、安装插件 根据用户们反馈的意见&#xff0c;这次重点对移动端兼容做了…

7个最佳WooCommerce跨境电商社交媒体插件

在互联的早期&#xff0c;您通常可以将产品直接放到网上并出售。但在今天你必须进行营销和做广告。如果没有包括社交媒体在内的可持续营销策略&#xff0c;您的商店可能会被忽视。值得高兴的是&#xff0c;有很多 WooCommerce跨境电商社交媒体插件可以用来传播信息&#xff0c;…

SpringBoot + Druid DataSource 实现监控 MySQL 性能

点击关注公众号&#xff0c;Java干货及时送达&#x1f447; 来源&#xff1a;blog.csdn.net/lvoelife/article/details/128092586 1. 基本概念 我们都使用过连接池&#xff0c;比如C3P0&#xff0c;DBCP&#xff0c;hikari&#xff0c; Druid&#xff0c;虽然HikariCP的速度稍快…

使用eNSP配置防火墙USG6000v双机热备(VGMP+HRP+OSPF+NAT)

目录 前言 实验拓扑 配置过程 一、导入设备包 二、登陆USG6000v 三、配置接口IP地址 四、配置防火墙安全区域 五、配置内网路由器协议OSPF 五、配置VRRP 六、配置IP-Link联动双机热备 八、配置安全策略 九、配置NAT 十、配置外网路由 配置验证 前言 本实验使用华…

chatgpt赋能python:Python访问路由器

Python访问路由器 路由器是网络连接设备的重要组成部分&#xff0c;用于将信息从一个网络传输到另一个网络。为了使路由器正常运行&#xff0c;需要对其进行配置和管理。Python作为一种广泛应用的编程语言&#xff0c;可以通过多种方式访问和控制路由器。在本文中&#xff0c;…

【运维】使用AP模式接入已有的SP路由器

1. 前言 在使用Parsec时&#xff0c;遇到一个问题&#xff1a;就是Client客户端在接入到Internet时&#xff0c;“最好”只经过一个路由器&#xff08;“Make sure your home isn’t using two routers”&#xff09;&#xff0c;Parsec官方给出的建议是通过AP模式接入SP的路由…

Python发送验证码短信

Python发送验证码短信 前提条件相关介绍实验环境发送验证码短信账户注册查看用户名查看密码主要步骤代码实现输出结果 前提条件 熟悉Python基本语法 相关介绍 Python是一种跨平台的计算机程序设计语言。是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被…

教育培训机构学生管理系统

摘 要 计算机网络如果结合使用信息管理系统&#xff0c;能够提高管理员管理的效率&#xff0c;改善服务质量。优秀的教育培训机构学生管理系统能够更有效管理教育培训机构学生信息业务规范&#xff0c;帮助管理者更加有效管理教育培训机构学生信息&#xff0c;可以帮助提高克服…

班级管理系统

摘要&#xff1a;在国家重视教育影响下&#xff0c;教育部门的密确配合下&#xff0c;对教育进行改革、多样性、质量等等的要求&#xff0c;使教育系统的管理和运营比过去十年前更加理性化。依照这一现实为基础&#xff0c;设计一个快捷而又方便的网上班级管理系统是一项十分重…

【学生管理系统】班级管理

目录 3. 班级管理 3.1 需求 3.1.1 添加班级 3.1.2 班级列表 3.2 搭建环境 3.2.1 前端实现 3.2.2 后端实现&#xff08;9010&#xff09; 3.3 添加班级 3.3.1 查询所有老师 3.3.2 【难】前端&#xff1a;选择老师 3.3.3 后端&#xff1a;添加班级 3.3.4 前端&#x…

postman解决session验证问题,试用验证码校验,带登录状态的请求

在测试后端接口时&#xff0c;我们经常会遇到某个接口是需要权限才能访问&#xff0c;如登录后才能访问&#xff0c;那postman如何模拟已登录的状态呢&#xff1f;再者&#xff0c;如果我们在做注册模块时&#xff0c;后端验证码生成并通过邮箱或短信发送给用户后&#xff0c;必…

TDengine高可用分布式集群详解

本文正在参与“拥抱开源|涛思数据TDengine有奖征稿&#xff1a;投稿地址。 文章目录 一、前言二、举个栗子1、努力工作的小T2、可怜的小T3、小T的老婆小D登场4、小T创业了5、平衡分配任务6、公司越做越大 三、分布式和集群概览1、单点1&#xff09;单点概念2&#xff09;单点故…

鹅厂发布的这个算力集群,最快4天训练万亿参数大模型

​| 文章来源于&#xff1a;“鹅厂技术派”公众号 大模型要成功&#xff0c;算力是关键。 这是腾讯云面向大模型训练场景&#xff0c;发布的全新一代的HCC高性能计算集群性能参数&#xff1a; “算力性能和上一代相比提升3倍&#xff0c;服务器接入带宽从1.6T提升到3.2T。”…