一. 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开发之消息系统.

一.Duilib开发之基本使用相关推荐

  1. duilib设置透明窗口_使用duilib开发半透明异形窗体程序(补充)

    距离上一篇半透明窗体的博客,已经过去一年,现在这几天又对Duilib进行了一些优化和修复.这次我把CRenderEngine的渲染函数都改成了基于Gdi+的.根据我的测试,因为Duilib所需的都是最 ...

  2. Duilib开发环境搭建

    1.到github上下载最新版本,https://github.com/duilib/duilib,也没有发现版本号,就如图所示吧 2.我只安装了VS2008,而github上的已经更新到VS2013 ...

  3. 使用duilib开发半透明异形窗体程序(附源码和demo)

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/43532791 半透明异形窗体的功能在之前维护的老版本的duilib里面已 ...

  4. duilib开发(五):界面布局

    代码仓库:https://github.com/yangpan4485/duilib/tree/develop/MyDemo 一.duilib 的几种界面布局 duilib 有着 6 大布局,分别是 ...

  5. duilib开发(八):duilib 实现 table switch

    代码仓库:https://github.com/yangpan4485/duilib/tree/develop/MyDemo 一.效果如下图所示 二.具体操作 1.拷贝 UIAnimation.cpp ...

  6. duilib制作窗体动画效果

    转载请说明原出处,谢谢~·http://blog.csdn.net/zhuhongshu/article/details/49026605 最近一段时间没写博客了,感觉最近没有遇到什么必须解决的bug ...

  7. 客户端开发GUI框架对比与技术选型总结

    客户端开发GUI框架对比与技术选型总结 客户端开发技术日新月易,目前客户端开发的GUI框架选型大致会从以下几个技术路线中进行选择: 纯系统原生GUI库 第三方库 基于Chromium + Node.j ...

  8. duilib创建自定义控件

    我之前也写过一片封装xml为一个容器的文章,只是写的很随意,仅仅贴出了一个demo的地址. 在群里还有一些刚刚接触duilib的朋友们问到duilib自定义控件的问题,这里我转载一篇redrain大佬 ...

  9. Duilib创建添加自定义控件

    本篇参考资料:Duilib自定义控件博文(duilib开发基础:创建自定义控件的过程):http://blog.csdn.net/zhuhongshu/article/details/45362751 ...

最新文章

  1. python中不同进制的整数之间可以直接运算_Python 进制转换、位运算
  2. 机器阅读理解(MRC)零基础入门级综述(一)
  3. 在 linux 下使用 CMake 构建应用程序
  4. arduino 上传项目出错_Arduino多核编程:简单例子
  5. 【报告分享】2022中国职业教育行业报告-多鲸资本.pdf(附下载链接)
  6. java调用Dos命令
  7. 适用于stuido one的虚拟贝斯手插件:UJAM Virtual Bassist ROYAL for Mac
  8. 安卓手机权限总结安卓权限列表
  9. Provisional headers are shown axios 超时处理
  10. 格式化U盘为FAT32
  11. Win11磁盘碎片整理在哪?Win11机械硬盘磁盘碎片整理方法
  12. JavaScript数据类型 - String类型
  13. 家用千兆路由器排行榜前十名_2019最适合家用路由器哪个好_排行榜_智能家
  14. UEditor上传漏洞修复
  15. HDU_1055 POJ_2054 Color a Tree(贪心)
  16. PhotoShopCS6_13.0.1.3
  17. 若依前后端分离框架学习-6:日志管理
  18. 跟着小甲鱼学python怎么样_跟着小甲鱼的python视频学习,小白能够接受吗?
  19. 黄金百战穿金甲,搞懂数据结构与算法!!!送福利
  20. [宅男福利]人人网相册批量下载器(下载红毯照ChinaJoy照神马的最方便了~!)...

热门文章

  1. 解决“无任何网络提供程序接受指定的网络路径”问题的几个方法
  2. VC++6.0遇到“error spawning cl.exe”的解决办法
  3. php接入微信支付,扫码支付和H5支付(非微信浏览器),基于thinkPHP框架 WeChatDeveloper支付类包 踩坑指南
  4. 巧用订阅功能增加营收|Google Play 线上培训营 · 三月第 1 期
  5. Flurry iOS端调研和使用
  6. 4G标准将统一:TD-LTE-Advanced或成唯一国际标准
  7. Sqlserver将人名转换为拼音函数
  8. 基于FPGA的4x4矩阵键盘控制器verilog开发实现
  9. 基于Labview平台的滚动轴承故障分析与噪声评价系统
  10. 3D中的方位和角位移(2)