duilib开发(七):复杂控件介绍

代码仓库: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 0
    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();
        }
    }
#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

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值