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

实现效果图

Demo源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,468评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,620评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,427评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,160评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,197评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,334评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,775评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,444评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,628评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,459评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,508评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,210评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,767评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,850评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,076评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,627评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,196评论 2 341

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,321评论 25 707
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,340评论 0 17
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,569评论 18 139
  • 《ijs》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 10...
    叶染柒丶阅读 5,038评论 0 7
  • 成长路上的艰难险阻数不胜数,但是,哪些才是决定性因素,归根结底是人的信仰。 我的一位老师,数十年坚持研究儿童的教育...
    修彦红阅读 678评论 0 1