欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Duilib总结与心得

程序员文章站 2022-07-08 10:46:08
...

原文链接https://www.jianshu.com/p/4474f7a9b8b6


不知不觉中使用Duilib已经两周有余了,在使用过程中遇到了很多问题,最终自己也有了一丢丢的认识见解,特记录并分享。

控件

控件及继承关系图

Duilib总结与心得

【Window】窗口

【Control】除Window外其他所有组件都继承自Control

布局:

【Container】

【VerticalLayout】垂直布局:其内元素按照竖直方式排列

【HorizontalLayout】水平布局:其内元素按照水平方式排列

【TileLayout】平铺布局:例如360工具箱。属性columns[列数,如(4)]与itemsize[子项固定大小,如(128,128)]不能同时使用。

【TabLayout】标签页,配合Option使用。

【ChildLayout】

功能控件:

【ActiveX】

【WebBrowser】浏览器

【Label】标签

【Button】按钮

【Text】文本

【Progress】--【Slider】进度条--进度条按钮

【Edit】输入框,支持showhtml。

【RichEdit】输入框,不支持showhtml。支持多行,直接打回车即可。

【Option】标签

【ScrollBar】滚动条

【GifAnimGif】动画

【Combo】下拉框

【List--ListHeader】--【ListHeaderItem】--【ListLabelElement】--【ListTextElement】--【ListContainerElement】列表

【TreeView】--【TreeNode】树

属性

详细属性查看官方Duilib文件夹内的"属性列表.xml"。

【name】控件名字,同一窗口内必须唯一。建议命名格式"控件类型名称",例如:"btnClose";"optionMain"。

【bkcolor】背景颜色。如:0xFFFFFFFF。一般的颜色RGB表示都是六位,这里的八位中的前两位为FF,后面六位与普通RGB颜色编码相同。RGB颜色参考

【bkcolor2】背景渐变色2,和bkcolor配合使用,如(0xFFFFFF00)。

【bkcolor3】背景渐变色3,和bkcolor、bkcolor2配合使用,如(0xFFFF00FF)"。

【bkimage】背景图片,如(bk.bmp或file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0' corner='0,0,0,0' mask='#FF0000' fade='255' hole='false' xtiled='false' ytiled='false')。

【width】控件预设的宽度,如(100)。

【height】控件预设的高度,如(30)。

【text】显示文本,如(测试文本)。

【tooltip】鼠标悬浮提示,如(请在这里输入你的密码)。

【enabled】是否可以响应用户操作,如(true)。

【mouse】本控件是否可以响应鼠标操作,如(true)。

【mousechild】本控件的子控件是否可以响应用户操作,如(true)。

【visible】是否可见,如(true)。

【menu】是否需要右键菜单。

【float】【pos】是否采用绝对定位以及位置(左上右下)。如float="true" pos="10,10,10,10"。只有float为true时,pos才有效,只有float为true,无pos时内容不显示。更多用法见补充的布局技巧

【padding】外边距,如(2,2,2,2)。边距不属于此控件。

【inset】容器的内边距,如(2,2,2,2)。边距属于此控件。

【bordercolor】边框颜色,如(0xFF000000)。

【focusbordercolor】获得焦点时边框的颜色,如(0xFFFF0000)。

【align】文字对齐方式。在option中可以取left、right、center、top、button,如(center)。

【textpadding】文字显示的边距,如(2,2,2,2)。

【endellipsis】句末显示不全是否使用...代替,如(true)"/>

【showhtml】是否使用类html富文本绘制,如(false)。

【vscrollbar】是否使用竖向滚动条,如(true)。只有内容超出容器后才会显示滚动条。
自己需要先定义vscrollbar滚动条

<Default name="VScrollBar" value="" />

【hscrollbar】是否使用横向滚动条,如(true)。只有内容超出容器后才会显示滚动条。

<Default name="HScrollBar" value="" />

【bkimage】【normalimage】【hotimage】【focusedimage】【pushedimage】【selectedimage】【disabledimage】
【textcolor】【hottextcolor】【focusedtextcolor】【pushedtextcolor】【selectedtextcolor】【disabledtextcolor】
普通状态--鼠标悬浮状态--获得焦点时状态--鼠标按下状态--选中状态--禁用状态
【foreimage】option,process,slider具有的前景图片。

实例

时间控件

<DateTime name="DateTimeDemo1" bkcolor="#FFE2E5EA"/> 

按钮

 <Button name="closebtn" tooltip="关闭"   float="true" pos="44,5,74,24" width="28" normalimage=" file='SysBtn\CloseNormal.bmp' " hotimage=" file='SysBtn\CloseFocus.bmp' " pushedimage=" file='SysBtn\CloseFocus.bmp' "/>

进度条

<Progress name="ProgressDemo1" text="Progress" width="100" height="20" foreimage="Progress/progress_fore.png" min="0" max="100" value="50" hor="true" align="center"/>
        
<Slider name="SliderDemo1" width="100" height="18" thumbsize="12,20" bkimage="file='Slider/slider_fore.bmp' mask='0xffff00ff'" thumbimage="file='Slider/SliderBar.png' mask='0xffffffff'"/>

下拉框

<Combo name="ComboDemo1" width="100" height="30" normalimage="file='ComboBox/Combo_nor.bmp'" hotimage="file='ComboBox/Combo_over.bmp' " pushedimage="file='ComboBox/Combo_over.bmp' ">
    <ListLabelElement text="zdy" selected="true"/>
    <ListLabelElement text="zzz"/>
</Combo>

编辑框

<Edit text="姜糖不语" font="2"  textcolor="#FF00a0e9" bordersize="2" bordercolor="#FF000000" focusbordercolor="#FFFF0000"/>

图片

<Container width="30" height="30" bkimage="file='SysBtn\setting_o.png'  dest='10,5,30,25'"/>

横线

<Control height="1" bkcolor="#FF000000"/>

导航栏与标签页

//需要配合逻辑代码实现
<Option name="OptionDemo1" text="1" bkcolor="#FFC5D4F2" group="tabDemo" selected="true"/>
<Option name="OptionDemo2" text="1" bkcolor="#FFFFDC78" group="tabDemo"/>
<Option name="OptionDemo3" text="1" bkcolor="#FFBECEA1" group="tabDemo"/>

<TabLayout name="tabTest" bkcolor="#FFB2D1E3">
    <HorizontalLayout>
        <Label text="Option1" bkcolor="#FFC5D4F2" align="center" />
    </HorizontalLayout>
    <HorizontalLayout>
        <Text  text="Option2" bkcolor="#FFFFDC78" align="center" />
    </HorizontalLayout>
    <HorizontalLayout>
        <Button  text="Option3" bkcolor="#FFBECEA1" align="center" />
    </HorizontalLayout>
</TabLayout>

注意那个按钮的实现。

<Default name="TreeNode" value="width="9999""/>
<TreeView vscrollbar="true" >   
    <TreeNode  height="24" folderattr="normalimage="file='SysBtn/list_icon_e.png' dest='6,6,18,18'" selectedimage="file='SysBtn/list_icon_f.png' dest='6,6,18,18'"" >
        <Text text="错误项" textcolor="#FFFF0000" font="3" float="true" pos="20,0,9999,9999" /> 
        <TreeNode text="xxx"  >
            <Button text="修复" textcolor="#FF1ddb6e" width="50"/>
        </TreeNode>
    </TreeNode>
</TreeView>

控件响应消息类型

原链接

消息 说明 Sender
click 鼠标点击 CButtonUI
dropdown 下拉显示 CComboUI
headerclick 点击列标题 CListHeaderItemUI
itemactivate   CListElementUI、CListContainerElementUI
itemclick 单击选项 CListLabelElementUI、CListContainerElementUI
itemselect 选择选项 CComboUI、CListUI
killfocus 失去焦点 CControlUI
link   CTextUI、CListTextElementUI
menu   CButtonUI、CControlUI
return 回车 CEditWnd、CRichEditUI
scroll 滚动 CScrollBarUI
selectchanged 变更选项 COptionUI
setfocus 获得焦点 CControlUI
showactivex   CActiveXUI
textchanged 文本被改变 CEditWnd
tabselect 标签页被选中 CTabLayoutUI
timer   CControlUI
valuechanged 值发生变化 CSliderUI
windowinit 窗体初始化

部分方法实现

SetText();
SetColor();
…

控件创建

增加控件:pNode->Add(pText);
TreeNode增加TreeNode:pNode->AddAt(pNodeLeaf, 0);

标签页

相关xml:

<!--导航栏-->
<HorizontalLayout height="113" bkcolor="#FF267FFC" bkcolor2="#FF0782FB">
    <HorizontalLayout width="920">
        <Option name="AdSafe1"  text="净网首页" align="right" textcolor="#FFFFFFFF" font="1" textpadding="0,0,20,0" normalimage="file='Option\Option1m.png' dest='36,36,76,76'"   hotimage="file='Option\Option1w.png' dest='36,36,76,76'" pushedimage="file='Option\Option1w.png' dest='36,36,76,76'" selectedimage="file='Option\Option1w.png' dest='36,36,76,76'" group="AdSafeOption" selected="true"/>
        <Option name="AdSafe2"  text="深度优化" align="right" textcolor="#FFFFFFFF" font="1" textpadding="0,0,20,0" normalimage="file='Option\Option2m.png' dest='36,36,76,76'"   hotimage="file='Option\Option2w.png' dest='36,36,76,76'" pushedimage="file='Option\Option2w.png' dest='36,36,76,76'" selectedimage="file='Option\Option2w.png' dest='36,36,76,76'" group="AdSafeOption" />
        <Option name="AdSafe3"  text="弹窗抓取" align="right" textcolor="#FFFFFFFF" font="1" textpadding="0,0,20,0" normalimage="file='Option\Option3m.png' dest='36,36,76,76'"   hotimage="file='Option\Option3w.png' dest='36,36,76,76'" pushedimage="file='Option\Option3w.png' dest='36,36,76,76'" selectedimage="file='Option\Option3w.png' dest='36,36,76,76'" group="AdSafeOption" />
        <Option name="AdSafe4"  text="拦截记录" align="right" textcolor="#FFFFFFFF" font="1" textpadding="0,0,20,0" normalimage="file='Option\Option4m.png' dest='36,36,76,76'"   hotimage="file='Option\Option4w.png' dest='36,36,76,76'" pushedimage="file='Option\Option4w.png' dest='36,36,76,76'" selectedimage="file='Option\Option4w.png' dest='36,36,76,76'" group="AdSafeOption" />
        <Option name="AdSafe5"  text="移动净网版" align="right" textcolor="#FFFFFFFF" font="1" textpadding="0,0,20,0" normalimage="file='Option\Option5m.png' dest='32,36,62,76'"   hotimage="file='Option\Option5w.png' dest='32,36,62,76'" pushedimage="file='Option\Option5w.png' dest='32,36,62,76'" selectedimage="file='Option\Option5w.png' dest='32,36,62,76'" group="AdSafeOption" />
    </HorizontalLayout>
    <HorizontalLayout />
</HorizontalLayout>
<!--窗体-->
<TabLayout name="AdSafeContent" bkcolor="#FFFFFFFF">
    <!-- <ChildLayout xmlfile="PageOne.xml" />
    <ChildLayout xmlfile="PageTwo.xml" />
    <ChildLayout xmlfile="PageThree.xml" />
    <ChildLayout xmlfile="PageFour.xml" />
    <ChildLayout xmlfile="PageFive.xml" /> -->
    <Include source="PageOne.xml" />
    <Include source="PageTwo.xml" />
    <Include source="PageThree.xml" />
    <Include source="PageFour.xml" /> 
    <Include source="PageFive.xml" />
</TabLayout>

相关代码片段:

if (msg.sType == _T("selectchanged"))
{
    CDuiString strName = msg.pSender->GetName();
    CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(m_PaintManager.FindControl(_T("AdSafeContent")));
    if (strName == _T("AdSafe1"))
    {
        pControl->SelectItem(0);
    }
    if (strName == _T("AdSafe2"))
    {
        pControl->SelectItem(1);
    }
    if (strName == _T("AdSafe3"))
    {
        pControl->SelectItem(2);
    }
    if (strName == _T("AdSafe4"))
    {
        pControl->SelectItem(3);
    }
    if (strName == _T("AdSafe5"))
    {
        pControl->SelectItem(4);
    }
}

Combo

相关xml:

 <Combo name="comboUpdateFrequency"  width="60" height="30" normalimage="file='ComboBox/Combo_nor.bmp' corner='5,2,30,2'" hotimage="file='ComboBox/Combo_over.bmp' corner='5,2,30,2'" pushedimage="file='ComboBox/Combo_over.bmp' corner='5,2,30,2'" >
    <ListLabelElement name="listDay" text=" 每天" selected="true"/>
    <ListLabelElement name="listWeek" text=" 每周" />
    <ListLabelElement name="listMonth" text=" 每月" />
</Combo>

相关代码片段:

void SetUpdateFrequency(int iUpdateFrequency)
    {
        CComboUI* pComboUpdateFrequency = static_cast<CComboUI*>(m_PaintManager.FindControl(_T("comboUpdateFrequency")));
        pComboUpdateFrequency->SetInternVisible(true);
        if (iUpdateFrequency == 0)
        {
            pComboUpdateFrequency->SelectItem(0);
        }
        else if (iUpdateFrequency == 1)
        {
            pComboUpdateFrequency->SelectItem(1);
        }
        else if (iUpdateFrequency == 2)
        {
            pComboUpdateFrequency->SelectItem(2);
        }
    }

补充

阴影实现

在WinMain入口函数内添加

CWndShadow::Initialize(hInstance);

在窗口类内定义一个成员变量

CWndShadow m_WndShadow;

在初始化窗口InitWindow函数内部进行实现

m_WndShadow.Create(m_hWnd);
m_WndShadow.SetSize(3);
m_WndShadow.SetDarkness(200);
//m_WndShadow.SetColor(0x0AFF00);
m_WndShadow.SetPosition(0, 0);

关于【ChildLayout】

作用就是从一个xml文件中加载布局来嵌入到ChildLayout布局所在的地方,使用这个布局一般只需要指定xmlfile属性来设置xml文件位置就可以了。他的意义在于可以把繁杂的大量xml代码分隔开。比如他和TabLayout布局结合,让TabLayout布局包含5个ChildLayout布局,而每个ChildLayout布局分别从5个xml文件加载自己的布局文件,这样就可以分块化的编写布局代码。

实际上有个比他更好用的标签,就是Include标签,Include不属于布局,但他的作用在布局方面非常类似ChildLayout,指定他的Source属性到某个xml文件就可以了。相对ChildLayout,Include的优点是可以自动识别自定义控件,而ChildLayout不可以!

布局技巧

1.一般是垂直布局,水平布局嵌套使用。

2.使用【inset】属性和【padding】。【inset】的边框依旧属于控件内部,而【padding】的边框不属于控件。

3.使用float。
float="0.5,0.5,0.5,0.5" pos="-10,-10,10,10"。在上一层控件的正中间。距离中间点左上右下都是10的矩形。

float="0.1,0.3,0.2,0.4" pos="0,0,0,0"。占据上一层控件的水平0.1-0.2,垂直0.3-0.4的区域。

关于在逻辑代码中SetPos无效的问题。

1.设置控件的Pos的时候控件必须已经Add到了某个Contain中,否则SetPos无效

2.如果一定想在之前设置的话,那么请使用SetAttribute ,转Duilib ApplyAttributeList和SetPos陷阱

Combo不显示值的问题

需要pCombo->SetInternVisible(true); 具体实例见上面的combo实例

RECT类型示例

RECT rc;
rc.left = 20;
rc.top = 0;
rc.right = 9999;
rc.bottom = 9999;
CTextUI* pText = new CTextUI;
pText->SetFloat(true);
pText->SetPos(rc);

TreeNode的bug

如果直接在TreeNode设置文字,那么textcolor属性无效,需要使用

itemattr="textcolor="#FFFF0000" font="3"" 

但是此属性在鼠标悬浮后失效(如果是黑色的无影响),目前为深入研究解决方案。所以推荐采用TreeNode嵌套Text实现。

不显示边框阴影

经过个人使用发现:window必须roundcorner属性才能实现阴影。

<Window size="920,600" mininfo="920,600"  roundcorner="5,5" caption="0,0,0,30" sizebox="4,4,4,4" >
</Window>

关于ini文件的读写以及一个坑

相对路径设置如下将跟cpp文件在同一目录

#define inisrc TEXT(".//config.ini")

使用方式

int iCloseStatus = GetPrivateProfileInt(TEXT("CloseStatus"), TEXT("status"), 1, inisrc);
int iUpdateFrequency = GetPrivateProfileInt(TEXT("Update"), TEXT("frequency"), 1, inisrc);
WritePrivateProfileString(TEXT("CloseStatus"), TEXT("status"), _T("0"), inisrc);
WritePrivateProfileString(TEXT("Update"), TEXT("frequency"), _T("0"), inisrc);

相关文件【config.ini】内容

[CloseStatus]
status=0
[Update]
frequency=0

实现效果图

Duilib总结与心得

Demo源码



作者:静候那一米阳光
链接:https://www.jianshu.com/p/4474f7a9b8b6
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。