代码仓库:https://github.com/yangpan4485/duilib/tree/develop/MyDemo

一、复杂控件介绍

1、ActiveX 浏览器控件

xml

<?xml version="1.0" encoding="UTF-8"?>
<Window size="960,540" mininfo="600,400" caption="0,0,0,32" sizebox="4,4,4,4"><Font id="0" shared="true" name="宋体" size="18" bold="false" underline="false" italic="false" /><Font id="1" shared="true" name="宋体" size="20" bold="false" underline="false" italic="false" /><Font id="2" shared="true" name="宋体" size="16" bold="false" underline="false" italic="false" /><VerticalLayout bkcolor="#FFDFFDF0" width="300" height="318">  <!-- 整个窗口使用 VerticalLayout 布局 --><ActiveX name="ActiveXDemo1" float="true" pos="60,40,0,0" width="800" height="400" /></VerticalLayout>
</Window>

complex_control.h

#pragma once#include "UIlib.h"class ComplexControl : public DuiLib::CWindowWnd, public DuiLib::INotifyUI
{
public:ComplexControl();~ComplexControl();void Init();bool CreateDUIWindow();void ShowWindow();LPCTSTR GetWindowClassName() const override;void Notify(DuiLib::TNotifyUI& msg) override;LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam);LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam);void OnClick(DuiLib::TNotifyUI& msg);private:void InitWindow();private:HINSTANCE _hInstance;DuiLib::CPaintManagerUI _paintManager{};HWND _ownerWnd{};
};

complex_control.cpp

ActiveX 控件和其它控件不一样的点就是要在创建的时候进行初始化操作,不然就会崩溃,所以在 OnCreate() 函数结束的时候要自己实现 InitWindow() 函数

#include "complex_control.h"#include <iostream>
#include <string>ComplexControl::ComplexControl()
{}ComplexControl::~ComplexControl()
{}void ComplexControl::Init()
{SetProcessDPIAware();_hInstance = GetModuleHandle(0);DuiLib::CPaintManagerUI::SetInstance(_hInstance);DuiLib::CPaintManagerUI::SetResourcePath(DuiLib::CPaintManagerUI::GetInstancePath() + +_T("resources"));
}
bool ComplexControl::CreateDUIWindow()
{_ownerWnd = Create(NULL, _T("Complex"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);if (!_ownerWnd){std::cout << "create dui window failed" << std::endl;return false;}return true;
}
void ComplexControl::ShowWindow()
{ShowModal();
}LPCTSTR ComplexControl::GetWindowClassName() const
{return _T("DUICOMPLEXFrame");
}
void ComplexControl::Notify(DuiLib::TNotifyUI& msg)
{if (msg.sType == _T("click")){OnClick(msg);}
}
LRESULT ComplexControl::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{LRESULT lRes = 0;switch (uMsg) {case WM_CREATE:lRes = OnCreate(uMsg, wParam, lParam);break;case WM_CLOSE:lRes = OnClose(uMsg, wParam, lParam);break;default:break;}if (_paintManager.MessageHandler(uMsg, wParam, lParam, lRes)){return lRes;}return __super::HandleMessage(uMsg, wParam, lParam);
}LRESULT ComplexControl::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam)
{_paintManager.Init(m_hWnd);DuiLib::CDialogBuilder builder;DuiLib::CControlUI* pRoot = builder.Create(_T("complexControl.xml"), (UINT)0, NULL, &_paintManager);_paintManager.AttachDialog(pRoot);_paintManager.AddNotifier(this);InitWindow();return 0;
}LRESULT ComplexControl::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam)
{return 0;
}void ComplexControl::OnClick(DuiLib::TNotifyUI& msg)
{}void ComplexControl::InitWindow()
{DuiLib::CActiveXUI* pActiveXUI = static_cast<DuiLib::CActiveXUI*>(_paintManager.FindControl(_T("ActiveXDemo1")));if (pActiveXUI){IWebBrowser2* pWebBrowser = NULL;pActiveXUI->SetDelayCreate(false);              // 相当于界面设计器里的DelayCreate属性改为FALSE,在duilib自带的FlashDemo里可以看到此属性为TRUE             pActiveXUI->CreateControl(CLSID_WebBrowser);    // 相当于界面设计器里的Clsid属性里填入{8856F961-340A-11D0-A96B-00C04FD705A2},建议用CLSID_WebBrowser,如果想看相应的值,请见<ExDisp.h>pActiveXUI->GetControl(IID_IWebBrowser2, (void**)&pWebBrowser);if (pWebBrowser != NULL){pWebBrowser->Navigate(L"https://www.baidu.com/", NULL, NULL, NULL, NULL);pWebBrowser->Release();}}
}

运行效果,打开的十 IE 浏览器,但是在我这会提示有脚本错误

2、Progress 进度条控件

xml 里面添加一个进度条控件,value=“0” 表示默认值设置为 0,添加一个 Button,当点击 Button 的时候进度条从 0 - 100,textpadding="0,6,0,0" 表示 value 的位置离 top 的距离为6,差不多在中间了,corner 可以参考这一篇文章:https://blog.csdn.net/CAir2/article/details/45936215,align=“center” 表示居中对齐,只是左右会居中对齐,hor 颜色的渐变方向,hor是水平方向,ver是垂直方向

<Progress name="progressControl" text="0" textpadding="0,6,0,0" float="true" pos="30,28,0,0" width="139" height="30" bkimage="file='common/progress_back.png' corner='5,4,4,5'" foreimage="common/progress_fore.png" min="0" max="100" value="0" hor="true" align="center" font="2" />
<Button name="startBtn" text="开始" pos="28,90,100,120" float="true" />

在 cpp 中对 OnClick 消息做出响应

if (msg.pSender->GetName() == _T("startBtn"))
{DuiLib::CProgressUI* pProgress = static_cast<DuiLib::CProgressUI*>(_paintManager.FindControl(_T("progressControl")));std::thread work = std::thread([pProgress, this]() {for (int i = 1; i <= 100; ++i) {pProgress->SetValue(i);std::string text = std::to_string(i) + "%";pProgress->SetText(text.c_str());Sleep(50);}});work.detach();
}

运行就可以看见进度条在动了

3、Slider 滑块控件

xml

<Slider name="sliderControl" float="true" pos="28,150,0,0" width="139" height="18" thumbsize="12,20" value="0" bkimage="file='common/SliderBar_BK.bmp' mask='0xffff00ff'" thumbimage="file='common/SliderBar_Thumb.png' mask='0xffffffff'"/>

在 cpp 中对可以接收 OnValueChange 消息,然后做出处理

if (msg.pSender->GetName() == _T("sliderControl"))
{DuiLib::CSliderUI* slider = static_cast<DuiLib::CSliderUI*>(_paintManager.FindControl(_T("sliderControl")));// 获取 slider 的进度std::cout << "slider:" << slider->GetValue() << std::endl;
}

4、List 列表控件

xml,在 xml 里面设置列表的头部,然后具体元素的添加在 cpp 中完成

<Default shared="true" name="List" value="headerbkimage=&quot;res='common/list_header_bg.png'&quot; itemalign=&quot;center&quot; itemlinecolor=&quot;#FF888888&quot; itemshowrowline=&quot;true&quot; itemshowcolumnline=&quot;true&quot;" />
<Default name="VScrollBar" shared="true" value="width=&quot;8&quot; showbutton1=&quot;false&quot; showbutton2=&quot;false&quot; thumbnormalimage=&quot;file='common/vscrollbar.png' source='0,60,8,100' corner='0,4,0,4'&quot; thumbhotimage=&quot;file='common/vscrollbar.png' source='8,60,16,100' corner='0,4,0,4'&quot; thumbpushedimage=&quot;file='common/vscrollbar.png' source='16,60,24,100' corner='0,4,0,4'&quot; railnormalimage=&quot;&quot; railhotimage=&quot;&quot; railpushedimage=&quot;&quot; raildisabledimage=&quot;&quot; bknormalimage=&quot;file='common/vscrollbar.png' source='0,0,8,60' corner='0,4,0,4'&quot; bkhotimage=&quot;&quot; bkpushedimage=&quot;&quot; bkdisabledimage=&quot;&quot; "/>
<Default name="HScrollBar" shared="true" value="height=&quot;8&quot; showbutton1=&quot;false&quot; showbutton2=&quot;false&quot; thumbnormalimage=&quot;file='common/hscrollbar.png' source='0,0,32,8' corner='4,0,4,0'&quot; thumbhotimage=&quot;file='common/hscrollbar.png' source='0,8,32,16' corner='4,0,4,0'&quot; thumbpushedimage=&quot;file='common/hscrollbar.png' source='0,16,32,24' corner='4,0,4,0'&quot; railnormalimage=&quot;&quot; railhotimage=&quot;&quot; railpushedimage=&quot;&quot; raildisabledimage=&quot;&quot; bknormalimage=&quot;file='common/hscrollbar.png' source='0,0,32,8' corner='4,0,4,0'&quot; bkhotimage=&quot;&quot; bkpushedimage=&quot;&quot; bkdisabledimage=&quot;&quot; "/>
<List name="listControl" float="true" pos="30,200,0,0" width="400" height="218" vscrollbar="true" hscrollbar="true" bkcolor="#FFFFFFFF" itemtextcolor="#FF000000" itembkcolor="#FFE2AADF" itemselectedtextcolor="#FF000000" itemselectedbkcolor="#FFC1E3FF" itemhottextcolor="#FF000000" itemhotbkcolor="#FFE9F5FF" itemdisabledtextcolor="#FFCCCCCC" itemdisabledbkcolor="#FFFFFFFF" ><ListHeader name="domain" bkimage="common/list_header_bg.png"><ListHeaderItem text="姓名" width="80" height="30" minwidth="25"  sepwidth="1" align="center" hotimage="common/list_header_hot.png" pushedimage="common/list_header_pushed.png" sepimage="common/list_header_sep.png" bkcolor="0xffaa00ff"/><ListHeaderItem text="学号" width="160" height="30" minwidth="25"  sepwidth="1" align="center" hotimage="common/list_header_hot.png" pushedimage="common/list_header_pushed.png" sepimage="common/list_header_sep.png" bkcolor="0xffaa00ff"/><ListHeaderItem text="成绩" width="160" height="30" minwidth="25"  sepwidth="1" align="center" hotimage="common/list_header_hot.png" pushedimage="common/list_header_pushed.png" sepimage="common/list_header_sep.png" bkcolor="0xffaa00ff"/></ListHeader>
</List>

cpp 添加元素

void ComplexControl::InitWindow()
{CListUI* pList = static_cast<CListUI*>(_paintManager.FindControl(_T("listControl")));for (int i = 0; i < 20; i++){CListTextElementUI* pItem = new CListTextElementUI();pItem->SetTag(i);pItem->SetFixedHeight(30);pList->Add(pItem);std::string number;if (i < 10){number = "100" + std::to_string(i);}else {number = "10" + std::to_string(i);}std::string score = std::to_string(i + 60);pItem->SetText(0, _T("张三"));pItem->SetText(1, _T(number.c_str()));pItem->SetText(2, _T(score.c_str()));}
}

5、RichEdit 控件

<RichEdit name="wordedit" pos="450,200,0,0" float="true" width="350" height="178" bkcolor="#FFFFFFFF" textcolor="#FFAAA001" font="0" password="false" tipvalue="请输入文字" mutiline="true" autovscroll="true" rich="false" vscrollbar="true" hscrollbar="false" autohscroll="false"/>
<Button name="okBtn" text="确定" pos="450,388,522,418" float="true" />

6、TreeView 控件

    <TreeView pos="850,20,1115,418" float="true" bkcolor="#FF111111" name="treePlaylist" childpadding="4" multipleitem="true" inset="4,0,3,0" bordersize="1" bordercolor="#FF2B2B2B" itemtextcolor="#FFC8C6CB" itemhottextcolor="#FFC8C6CB" selitemtextcolor="#FFC8C6CB" itemhotbkcolor="#FF1B1B1B" itemselectedbkcolor="#FF151C2C" vscrollbar="true" hscrollbar="true" ><TreeNode name="nodePlaylist" text="播放列表" height="33" bkimage="common/treeview_header.png" itemattr="valign=&quot;vcenter&quot; font=&quot;1&quot; textpadding=&quot;12,0,0,0&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"><TreeNode text="迅雷下载" inset="-8,0,0,0" height="22" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot; textpadding=&quot;4,0,0,0&quot;" folderattr="padding=&quot;0,5,0,0&quot; width=&quot;12&quot; height=&quot;12&quot; selectedimage=&quot;file='common/treeview_expand.png' source='0,0,12,12' &quot; normalimage=&quot;file='common/treeview_expand.png' source='13,0,25,12' &quot;"><TreeNode text="下载1" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/><TreeNode text="下载2" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode></TreeNode><TreeNode name="onlineMedialist" text="在线媒体" height="33" bkimage="common/treeview_header.png" itemattr="valign=&quot;vcenter&quot; font=&quot;1&quot; textpadding=&quot;12,0,0,0&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"><TreeNode text="今日热播" inset="-8,0,0,0" height="22" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot; textpadding=&quot;4,0,0,0&quot;" folderattr="padding=&quot;0,5,0,0&quot; width=&quot;12&quot; height=&quot;12&quot; selectedimage=&quot;file='common/treeview_expand.png' source='0,0,12,12' &quot; normalimage=&quot;file='common/treeview_expand.png' source='13,0,25,12' &quot;"><TreeNode text="八公" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/><TreeNode text="HACHI" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode><TreeNode text="热点新闻" inset="-8,0,0,0" height="22" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot; textpadding=&quot;4,0,0,0&quot;" folderattr="padding=&quot;0,5,0,0&quot; width=&quot;12&quot; height=&quot;12&quot; selectedimage=&quot;file='common/treeview_expand.png' source='0,0,12,12' &quot; normalimage=&quot;file='common/treeview_expand.png' source='13,0,25,12' &quot;"><TreeNode text="八公" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/><TreeNode text="HACHI" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode></TreeNode><TreeNode name="gameCenterlist" text="娱乐中心" height="33" bkimage="common/treeview_header.png" itemattr="valign=&quot;vcenter&quot; font=&quot;1&quot; textpadding=&quot;12,0,0,0&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"><TreeNode text="短视频广场" inset="-8,0,0,0" height="22" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot; textpadding=&quot;4,0,0,0&quot;" folderattr="padding=&quot;0,5,0,0&quot; width=&quot;12&quot; height=&quot;12&quot; selectedimage=&quot;file='common/treeview_expand.png' source='0,0,12,12' &quot; normalimage=&quot;file='common/treeview_expand.png' source='13,0,25,12' &quot;"><TreeNode text="热门视频" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/><TreeNode text="美女视频" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode><TreeNode text="直播频道" height="22" inset="8,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode></TreeView>

折叠 TreeView

void ComplexControl::OnItemClick(DuiLib::TNotifyUI& msg)
{auto name = msg.pSender->GetName();DuiLib::CTreeNodeUI* treeNode = nullptr;if (name == "nodePlaylist"){treeNode = static_cast<DuiLib::CTreeNodeUI*>(_paintManager.FindControl(_T("nodePlaylist")));}else if (name == "onlineMedialist"){treeNode = static_cast<DuiLib::CTreeNodeUI*>(_paintManager.FindControl(_T("onlineMedialist")));}else if (name == "gameCenterlist"){treeNode = static_cast<DuiLib::CTreeNodeUI*>(_paintManager.FindControl(_T("gameCenterlist")));}if (treeNode && treeNode->IsHasChild()) {CTreeViewUI  * pTreeView = treeNode->GetTreeView();if (NULL != pTreeView) {CCheckBoxUI* pFolder = treeNode->GetFolderButton();pFolder->Selected(!pFolder->IsSelected());treeNode->SetVisibleTag(!pFolder->GetCheck());pTreeView->SetItemExpand(!pFolder->GetCheck(), treeNode);}}
}

7、DateTime 日期时间控件

xml

<DateTime name="dataTime" pos="450,30,650,70" float="true" bordersize="1" bordercolor="#FF888888" textpadding="3" bkcolor="#FFE2E5EA" font="2"/>

8、Container 容器控件,可以使用 Container 显示两张图片,也可以在 container 控件里面添加其它的控件,方便管理

xml

<Container pos="450,90,550,200" float="true" bkimage="file='common/test.jpg' dest='0,5,98,105'" />
<Container pos="550,90,650,200" float="true" bkimage="file='common/test.jpg' dest='2,5,100,105'" />

9、Control 控件,利用 Control 控件显示横线和竖线

<Control pos="450,80,650,85" float="true" bkcolor="#FF000000"/>
<Control pos="250,20,255,160" float="true" bkcolor="#FF000000"/>

10、全部代码

xml

<?xml version="1.0" encoding="UTF-8"?>
<Window size="1200,600" mininfo="600,400" caption="0,0,0,32" sizebox="4,4,4,4"><Font id="0" shared="true" name="宋体" size="18" bold="false" underline="false" italic="false" /><Font id="1" shared="true" name="宋体" size="20" bold="false" underline="false" italic="false" /><Font id="2" shared="true" name="宋体" size="16" bold="false" underline="false" italic="false" /><Font id="3" shared="true" name="宋体" size="16" bold="false" underline="false" italic="false" /><Font id="4" shared="true" name="宋体" size="16" bold="false" underline="false" italic="false" /><Default shared="true" name="Button" value=" height=&quot;30&quot; width=&quot;100&quot; normalimage=&quot;file=&apos;common/button_normal.bmp&apos;&quot; hotimage=&quot;file=&apos;common/button_over.bmp&apos;&quot; pushedimage=&quot;file=&apos;common/button_down.bmp&apos;&quot; font=&quot;0&quot;" /><Default shared="true" name="List" value="headerbkimage=&quot;res='common/list_header_bg.png'&quot; itemalign=&quot;center&quot; itemlinecolor=&quot;#FF888888&quot; itemshowrowline=&quot;true&quot; itemshowcolumnline=&quot;true&quot;" /><Default name="VScrollBar" shared="true" value="width=&quot;8&quot; showbutton1=&quot;false&quot; showbutton2=&quot;false&quot; thumbnormalimage=&quot;file='common/vscrollbar.png' source='0,60,8,100' corner='0,4,0,4'&quot; thumbhotimage=&quot;file='common/vscrollbar.png' source='8,60,16,100' corner='0,4,0,4'&quot; thumbpushedimage=&quot;file='common/vscrollbar.png' source='16,60,24,100' corner='0,4,0,4'&quot; railnormalimage=&quot;&quot; railhotimage=&quot;&quot; railpushedimage=&quot;&quot; raildisabledimage=&quot;&quot; bknormalimage=&quot;file='common/vscrollbar.png' source='0,0,8,60' corner='0,4,0,4'&quot; bkhotimage=&quot;&quot; bkpushedimage=&quot;&quot; bkdisabledimage=&quot;&quot; "/><Default name="HScrollBar" shared="true" value="height=&quot;8&quot; showbutton1=&quot;false&quot; showbutton2=&quot;false&quot; thumbnormalimage=&quot;file='common/hscrollbar.png' source='0,0,32,8' corner='4,0,4,0'&quot; thumbhotimage=&quot;file='common/hscrollbar.png' source='0,8,32,16' corner='4,0,4,0'&quot; thumbpushedimage=&quot;file='common/hscrollbar.png' source='0,16,32,24' corner='4,0,4,0'&quot; railnormalimage=&quot;&quot; railhotimage=&quot;&quot; railpushedimage=&quot;&quot; raildisabledimage=&quot;&quot; bknormalimage=&quot;file='common/hscrollbar.png' source='0,0,32,8' corner='4,0,4,0'&quot; bkhotimage=&quot;&quot; bkpushedimage=&quot;&quot; bkdisabledimage=&quot;&quot; "/><VerticalLayout bkcolor="#FFDFFDF0">  <!-- 整个窗口使用 VerticalLayout 布局 --><Progress name="progressControl" text="0" textpadding="0,6,0,0" float="true" pos="30,28,0,0" width="139" height="30" bkimage="file='common/progress_back.png' corner='5,4,4,5'" foreimage="common/progress_fore.png" min="0" max="100" value="0" hor="true" align="center" font="2" /><Button name="startBtn" text="开始" pos="28,90,100,120" float="true" /><Slider name="sliderControl" float="true" pos="28,150,0,0" width="139" height="18" thumbsize="12,20" value="0" bkimage="file='common/SliderBar_BK.bmp' mask='0xffff00ff'" thumbimage="file='common/SliderBar_Thumb.png' mask='0xffffffff'"/><List name="listControl" float="true" pos="30,200,0,0" width="400" height="218" vscrollbar="true" hscrollbar="true" bkcolor="#FFFFFFFF" itemtextcolor="#FF000000" itembkcolor="#FFE2AADF" itemselectedtextcolor="#FF000000" itemselectedbkcolor="#FFC1E3FF" itemhottextcolor="#FF000000" itemhotbkcolor="#FFE9F5FF" itemdisabledtextcolor="#FFCCCCCC" itemdisabledbkcolor="#FFFFFFFF" ><ListHeader name="domain" bkimage="common/list_header_bg.png"><ListHeaderItem text="姓名" width="80" height="30" minwidth="25"  sepwidth="1" align="center" hotimage="common/list_header_hot.png" pushedimage="common/list_header_pushed.png" sepimage="common/list_header_sep.png" bkcolor="0xffaa00ff"/><ListHeaderItem text="学号" width="160" height="30" minwidth="25"  sepwidth="1" align="center" hotimage="common/list_header_hot.png" pushedimage="common/list_header_pushed.png" sepimage="common/list_header_sep.png" bkcolor="0xffaa00ff"/><ListHeaderItem text="成绩" width="160" height="30" minwidth="25"  sepwidth="1" align="center" hotimage="common/list_header_hot.png" pushedimage="common/list_header_pushed.png" sepimage="common/list_header_sep.png" bkcolor="0xffaa00ff"/></ListHeader></List><RichEdit name="wordedit" pos="450,200,0,0" float="true" width="350" height="178" bkcolor="#FFFFFFFF" textcolor="#FFAAA001" font="0" password="false" tipvalue="请输入文字" mutiline="true" autovscroll="true" rich="false" vscrollbar="true" hscrollbar="false" autohscroll="false"/><Button name="okBtn" text="确定" pos="450,388,522,418" float="true" /><DateTime name="dataTime" pos="450,30,650,70" float="true" bordersize="1" bordercolor="#FF888888" textpadding="3" bkcolor="#FFE2E5EA" font="2"/><Control pos="450,80,650,85" float="true" bkcolor="#FF000000"/><Control pos="250,20,255,160" float="true" bkcolor="#FF000000"/><Container pos="450,90,550,200" float="true" bkimage="file='common/test.jpg' dest='0,5,98,105'" /><Container pos="550,90,650,200" float="true" bkimage="file='common/test.jpg' dest='2,5,100,105'" /><TreeView pos="850,20,1115,418" float="true" bkcolor="#FF111111" name="treePlaylist" childpadding="4" multipleitem="true" inset="4,0,3,0" bordersize="1" bordercolor="#FF2B2B2B" itemtextcolor="#FFC8C6CB" itemhottextcolor="#FFC8C6CB" selitemtextcolor="#FFC8C6CB" itemhotbkcolor="#FF1B1B1B" itemselectedbkcolor="#FF151C2C" vscrollbar="true" hscrollbar="true" ><TreeNode name="nodePlaylist" text="播放列表" height="33" bkimage="common/treeview_header.png" itemattr="valign=&quot;vcenter&quot; font=&quot;1&quot; textpadding=&quot;12,0,0,0&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"><TreeNode text="迅雷下载" inset="-8,0,0,0" height="22" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot; textpadding=&quot;4,0,0,0&quot;" folderattr="padding=&quot;0,5,0,0&quot; width=&quot;12&quot; height=&quot;12&quot; selectedimage=&quot;file='common/treeview_expand.png' source='0,0,12,12' &quot; normalimage=&quot;file='common/treeview_expand.png' source='13,0,25,12' &quot;"><TreeNode text="下载1" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/><TreeNode text="下载2" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode></TreeNode><TreeNode name="onlineMedialist" text="在线媒体" height="33" bkimage="common/treeview_header.png" itemattr="valign=&quot;vcenter&quot; font=&quot;1&quot; textpadding=&quot;12,0,0,0&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"><TreeNode text="今日热播" inset="-8,0,0,0" height="22" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot; textpadding=&quot;4,0,0,0&quot;" folderattr="padding=&quot;0,5,0,0&quot; width=&quot;12&quot; height=&quot;12&quot; selectedimage=&quot;file='common/treeview_expand.png' source='0,0,12,12' &quot; normalimage=&quot;file='common/treeview_expand.png' source='13,0,25,12' &quot;"><TreeNode text="八公" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/><TreeNode text="HACHI" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode><TreeNode text="热点新闻" inset="-8,0,0,0" height="22" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot; textpadding=&quot;4,0,0,0&quot;" folderattr="padding=&quot;0,5,0,0&quot; width=&quot;12&quot; height=&quot;12&quot; selectedimage=&quot;file='common/treeview_expand.png' source='0,0,12,12' &quot; normalimage=&quot;file='common/treeview_expand.png' source='13,0,25,12' &quot;"><TreeNode text="八公" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/><TreeNode text="HACHI" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode></TreeNode><TreeNode name="gameCenterlist" text="娱乐中心" height="33" bkimage="common/treeview_header.png" itemattr="valign=&quot;vcenter&quot; font=&quot;1&quot; textpadding=&quot;12,0,0,0&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"><TreeNode text="短视频广场" inset="-8,0,0,0" height="22" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot; textpadding=&quot;4,0,0,0&quot;" folderattr="padding=&quot;0,5,0,0&quot; width=&quot;12&quot; height=&quot;12&quot; selectedimage=&quot;file='common/treeview_expand.png' source='0,0,12,12' &quot; normalimage=&quot;file='common/treeview_expand.png' source='13,0,25,12' &quot;"><TreeNode text="热门视频" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/><TreeNode text="美女视频" height="22" inset="7,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;4&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode><TreeNode text="直播频道" height="22" inset="8,0,0,0" itemattr="valign=&quot;vcenter&quot; font=&quot;0&quot;" folderattr="width=&quot;0&quot; float=&quot;true&quot;"/></TreeNode></TreeView></VerticalLayout>
</Window>

.h

#pragma once#include "UIlib.h"class ComplexControl : public DuiLib::CWindowWnd, public DuiLib::INotifyUI
{
public:ComplexControl();~ComplexControl();void Init();bool CreateDUIWindow();void ShowWindow();LPCTSTR GetWindowClassName() const override;void Notify(DuiLib::TNotifyUI& msg) override;LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam);LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam);void OnClick(DuiLib::TNotifyUI& msg);void OnValueChange(DuiLib::TNotifyUI& msg);void OnItemClick(DuiLib::TNotifyUI& msg);private:void InitWindow();private:HINSTANCE _hInstance;DuiLib::CPaintManagerUI _paintManager{};HWND _ownerWnd{};
};

.cpp

#include "complex_control.h"#include <iostream>
#include <string>
#include <thread>
#include <chrono>using namespace DuiLib;ComplexControl::ComplexControl()
{}ComplexControl::~ComplexControl()
{}void ComplexControl::Init()
{SetProcessDPIAware();_hInstance = GetModuleHandle(0);DuiLib::CPaintManagerUI::SetInstance(_hInstance);DuiLib::CPaintManagerUI::SetResourcePath(DuiLib::CPaintManagerUI::GetInstancePath() + +_T("..\\..\\..\\resources"));
}
bool ComplexControl::CreateDUIWindow()
{_ownerWnd = Create(NULL, _T("Complex"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);if (!_ownerWnd){std::cout << "create dui window failed" << std::endl;return false;}return true;
}
void ComplexControl::ShowWindow()
{ShowModal();
}LPCTSTR ComplexControl::GetWindowClassName() const
{return _T("DUICOMPLEXFrame");
}
void ComplexControl::Notify(DuiLib::TNotifyUI& msg)
{if (msg.sType == _T("click")){OnClick(msg);}else if (msg.sType == _T("valuechanged")){OnValueChange(msg);}else if (msg.sType == _T("itemclick")){OnItemClick(msg);}
}
LRESULT ComplexControl::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{LRESULT lRes = 0;switch (uMsg) {case WM_CREATE:lRes = OnCreate(uMsg, wParam, lParam);break;case WM_CLOSE:lRes = OnClose(uMsg, wParam, lParam);break;default:break;}if (_paintManager.MessageHandler(uMsg, wParam, lParam, lRes)){return lRes;}return __super::HandleMessage(uMsg, wParam, lParam);
}LRESULT ComplexControl::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam)
{_paintManager.Init(m_hWnd);DuiLib::CDialogBuilder builder;DuiLib::CControlUI* pRoot = builder.Create(_T("complexControl.xml"), (UINT)0, NULL, &_paintManager);_paintManager.AttachDialog(pRoot);_paintManager.AddNotifier(this);InitWindow();return 0;
}LRESULT ComplexControl::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam)
{return 0;
}void ComplexControl::OnClick(DuiLib::TNotifyUI& msg)
{if (msg.pSender->GetName() == _T("startBtn")){DuiLib::CProgressUI* pProgress = static_cast<DuiLib::CProgressUI*>(_paintManager.FindControl(_T("progressControl")));std::thread work = std::thread([pProgress, this]() {for (int i = 1; i <= 100; ++i) {pProgress->SetValue(i);std::string text = std::to_string(i) + "%";pProgress->SetText(text.c_str());Sleep(50);}});work.detach();}if (msg.pSender->GetName() == _T("okBtn")){// 如果有手动输入的换行,字符会被覆盖掉DuiLib::CRichEditUI* pRichEdit = static_cast<DuiLib::CRichEditUI*>(_paintManager.FindControl(_T("wordedit")));std::cout << pRichEdit->GetText() << std::endl;}
}void ComplexControl::OnValueChange(DuiLib::TNotifyUI& msg)
{if (msg.pSender->GetName() == _T("sliderControl")){DuiLib::CSliderUI* slider = static_cast<DuiLib::CSliderUI*>(_paintManager.FindControl(_T("sliderControl")));// 获取 slider 的进度std::cout << "slider:" << slider->GetValue() << std::endl;}
}void ComplexControl::OnItemClick(DuiLib::TNotifyUI& msg)
{auto name = msg.pSender->GetName();DuiLib::CTreeNodeUI* treeNode = nullptr;if (name == "nodePlaylist"){treeNode = static_cast<DuiLib::CTreeNodeUI*>(_paintManager.FindControl(_T("nodePlaylist")));}else if (name == "onlineMedialist"){treeNode = static_cast<DuiLib::CTreeNodeUI*>(_paintManager.FindControl(_T("onlineMedialist")));}else if (name == "gameCenterlist"){treeNode = static_cast<DuiLib::CTreeNodeUI*>(_paintManager.FindControl(_T("gameCenterlist")));}if (treeNode && treeNode->IsHasChild()) {CTreeViewUI  * pTreeView = treeNode->GetTreeView();if (NULL != pTreeView) {CCheckBoxUI* pFolder = treeNode->GetFolderButton();pFolder->Selected(!pFolder->IsSelected());treeNode->SetVisibleTag(!pFolder->GetCheck());pTreeView->SetItemExpand(!pFolder->GetCheck(), treeNode);}}
}void ComplexControl::InitWindow()
{CListUI* pList = static_cast<CListUI*>(_paintManager.FindControl(_T("listControl")));for (int i = 0; i < 20; i++){CListTextElementUI* pItem = new CListTextElementUI();pItem->SetTag(i);pItem->SetFixedHeight(30);pList->Add(pItem);std::string number;if (i < 10){number = "100" + std::to_string(i);}else {number = "10" + std::to_string(i);}std::string score = std::to_string(i + 60);pItem->SetText(0, _T("张三"));pItem->SetText(1, _T(number.c_str()));pItem->SetText(2, _T(score.c_str()));}
#if 0DuiLib::CActiveXUI* pActiveXUI = static_cast<DuiLib::CActiveXUI*>(_paintManager.FindControl(_T("ActiveXDemo1")));if (pActiveXUI){IWebBrowser2* pWebBrowser = NULL;pActiveXUI->SetDelayCreate(false);              // 相当于界面设计器里的DelayCreate属性改为FALSE,在duilib自带的FlashDemo里可以看到此属性为TRUE             pActiveXUI->CreateControl(CLSID_WebBrowser);    // 相当于界面设计器里的Clsid属性里填入{8856F961-340A-11D0-A96B-00C04FD705A2},建议用CLSID_WebBrowser,如果想看相应的值,请见<ExDisp.h>pActiveXUI->GetControl(IID_IWebBrowser2, (void**)&pWebBrowser);if (pWebBrowser != NULL){pWebBrowser->Navigate(L"https://www.baidu.com/", NULL, NULL, NULL, NULL);pWebBrowser->Release();}}
#endif
}

运行结果

二、参考资料

1、duilib 复杂控件介绍:https://blog.csdn.net/rundll64/article/details/24749287?utm_medium=distribute.pc_relevant.none-task-blog-title-12&spm=1001.2101.3001.4242

2、duilib 中基于 wke 的浏览器控件:https://blog.csdn.net/lionzl/article/details/52449413

3、改进 RichEdit 的部分功能:https://blog.csdn.net/zhuhongshu/article/details/41208207

4、RichEdit 源码分析:https://blog.csdn.net/jcx517266098/article/details/79374671

5、TreeView 控件:https://www.cnblogs.com/Alberl/p/3402328.html

6、TreeView 折叠:https://blog.csdn.net/eGirlAsm/article/details/51010862

duilib开发(七):复杂控件介绍相关推荐

  1. 暑期实训 轻骑兵开发平台 前端控件介绍

    前端控件介绍 1. Layui 平台使用 Layui 作为主要的前端框架,它的特点是简单.高效.模块化,相 比于其他方案,Layui 的特殊之处也在于它的模块化.在 js 代码中,用到哪个模 块就引入 ...

  2. .NET(C#、VB)移动开发——Smobiler平台控件介绍:TextTabBar控件

    2019独角兽企业重金招聘Python工程师标准>>> TextTabBar控件 样式一 我们要实现上图中的效果,需要如下的操作: 从工具栏上的"Smobiler Comp ...

  3. .NET(C#、VB)APP开发——Smobiler平台控件介绍:BarcodeReader组件

    本文简述如何在Smobiler中使用BarcodeReader组件进行条码识别.Barcodereader通过机器学习能识别不规则条码,效率更好. Step 1. 新建一个SmobilerForm窗体 ...

  4. .NET(C#、VB)APP开发——Smobiler平台控件介绍:OCR组件

    本文简述如何在Smobiler中使用OCR组件进行文字识别. Step 1. 新建一个SmobilerForm窗体,并在窗体中加入OCR和Button,布局如下 Button的点击事件代码: priv ...

  5. .NET(C#、VB)APP开发——Smobiler平台控件介绍:PDFView

    本文简述如何在Smobiler中使用PDFView. Step 1. 新建一个SmobilerForm窗体,再拖入PDfView,布局如下 PDFView.ResourcrPath默认Document ...

  6. .NET(C#、VB)APP开发——Smobiler平台控件介绍:ArcFace人脸识别

    本文简述如何在Smobiler中使用ArcFace(虹软人脸识别). Step 1. 新建一个SmobilerForm窗体,再拖入Button,Label,TextBox和AcrFace,布局如下 在 ...

  7. .NET(C#、VB)APP开发——Smobiler平台控件介绍:TTS

    本文简述如何在Smobiler中使用TTS文字转语音. Step 1. 新建一个SmobilerForm窗体,并在窗体中加入TTS和Button,布局如下 Button的点击事件代码: private ...

  8. .NET(C#、VB)APP开发——Smobiler平台控件介绍:FingerPrint指纹识别组件

    本文简述如何在Smobiler中使用FingerPrint. Step 1. 新建一个SmobilerForm窗体,并在窗体中加入FingerPrint和Button,布局如下 Button的点击事件 ...

  9. Web开发中的弹出对话框控件介绍

    Web开发中,目前由于Jquery的大行其道,因此很多弹出对话框,都用到了Jquery技术,反而原始的弹出对话框的方式较为少用了.不过基于JQuery的方式实现对话框窗口弹出,也有很多控件可以利用,由 ...

  10. iOS开发UI篇—UIScrollView控件介绍

    iOS开发UI篇-UIScrollView控件介绍 一.知识点简单介绍 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤大⼩小是极其有限的,因此直接展⽰示在⽤用户眼前的内容也相当有限 ...

最新文章

  1. 深入Hotspot源码,搞清楚JVM的本质
  2. 麦肯锡:企业数字化转型不要被技术“绑架”
  3. javascript高级程序设计(第3版)之《script元素》
  4. mysql+8.0+新特性_MySQL 8.0的一些新特性汇总大全
  5. 工业环境老鼠目标检测
  6. 将一组数进行排序后,也输出他与之对应的序号
  7. 《四世同堂》金句摘抄(七)
  8. laravel 分词搜索匹配度_【地名地址】面向智慧城市的高精度地名地址匹配方法...
  9. linux编写复制脚本程,常用的Shell脚本
  10. linux内核的队列实现移植
  11. Vue.js 系列教程 5:动画
  12. Scene窗口—Scene视图导航
  13. 大数据领域一些值得读的论文(不断更新
  14. 应届生参加工作,什么事情越早知道越好?
  15. 2022化工自动化控制仪表考试题及答案
  16. 【激励自己】牛人职场分享汇总
  17. .NET MongoDB Driver GridFS 2.2原理及使用示例
  18. Win10、Win11打开远程桌面连接方法
  19. 一款基于 Spring Boot 的神仙接私活项目,已开源,2022 接私活必备!
  20. 计算机主板尺寸,电脑主板大中小三个等级的尺寸是多少?

热门文章

  1. 【第十届“泰迪杯”数据挖掘挑战赛】C题:疫情背景下的周边游需求图谱分析 赛后总结、46页论文及代码
  2. 人大金仓数据库高可用集群部署教程
  3. itest听力答案2020_itest答案
  4. 微型计算机天逸510s光驱,天逸510s Mini兼macOS BigSur安装教程
  5. 什么是RS-232-C接口与什么是RS-485接口?
  6. html5网页计数器,HTML5:启动计数器
  7. 【ArcGIS微课1000例】0032:ArcGIS中河流(曲线)、湖泊(水体色)图例制作案例教程
  8. 8个免费和最佳开源视频流服务器软件
  9. 基于树莓派的AirPlay功能实现
  10. unity3d 绘制小地图_Unity3D —— 小地图制作插件NJG MiniMap