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