Duilib教程-控件练习

一、控件消息的响应。

在HelloDuilib例子中,程序不能退出,在这里,我将添加一个关闭按钮,当点击它时,调用PostQuitMessage进行退出。

首先在界面的右上角添加一个关闭按钮,并取名为“btnClose”。

然后在 CHelloDuilibWnd 中重载 WindowImplBase::Notify ();

代码如下:

void CHelloDuilibWnd::Notify( TNotifyUI& msg )
{
    if (msg.sType == DUI_MSGTYPE_CLICK) // 先判断消息类型,如果是单击
    {
        if (msg.pSender->GetName() == _T ("btnClose")) // 如果控件名为 btnClose
        {
            PostQuitMessage(0);
        }
    }
}

如是即可退出程序。

二、获取XML中的控件。

一般的情况下,可以在窗口初始化的时候获取一个控件,当然你在什么时候获取都是可以的,在初始化获取,以后你就可以任意地使用了。

添加重载函数:WindowImplBae::InitWindow,代码如下:

void CHelloDuilibWnd::InitWindow()
{
    m_btnClose = static_cast <CButtonUI*> (m_PaintManager.FindControl(_T ("btnCloase")));
    ASSERT(m_btnClose != NULL);
}

把上面我们添加的关闭按钮对象保存起来。

请注意,是使用 m_PaintManager 进行获取,该对象负责管理所有工作,包括消息的传递,调用控件的绘制函数等,均由它处理。

三、标题栏

窗口有一个属性 caption 指定了窗口标题栏的位置。默认0代表了窗口的最大值。比如说,我们想要标题栏高度为30像素,即可设为:(0,0,0,30)。left, top, right都为0,只有bottom为30,right为0表示为最右边。当然如果全部设为0,会被认为没有标题栏。

四、示例程序的练习。

在这里,我并不会为你介绍所有控件的编写,只是作一个简单的介绍,然后控件的编写还需要你自己动手,只有自己写过的代码才是掌握了的代码。如果以每天学一个控件的效率的话,大概顶多两周即基本掌握所有控件的写法。下面是我以前学习的一个例子,截图如下,最后我也会附件贴上,希望对您的学习有所帮助。

当然我并没有编写所有的控件,比如menu、progressbar、sliderbar、tree等控件,这个示例是好久以前写的了。

关于控件特定的属性,如果你用心用过 DuiDesigner.exe的话,相信你已经知道它在哪里了,DuiDesigner会将每个控件的特殊的属性,单独列出来,如下图中Button控件的属性:

其它控件亦是如此。

1.控件的基本属性:

1)Name,名称,即类 CControlUI::GetName () 所返回的值。

2)Text, 标题

3)TextPadding,文字偏移。比如文字从第2个像素开始显示,则可设为(2,0,0,0)。注意,如果是使用单选框或是复选框,一定要使用到这个属性,使文字显示在图片的右边,即TextPadding的left为设置为图片的宽或更宽。

4)ShowHtml,标志Text属性的值是否为html。注意:这里的HTML并不是真的HTML,它不能使用HTML标签,只能使用内定的,如<i> 表示图片或文字倾斜等。

5)EndEllipsis,标志Text属性,当显示不完全时,最后是否以 ... 进行显示。

关于float及 Layout 的 insert、childpadding、hscrollbar、vscrollbar等属性,我会在自动布局中进行说明。

2.控件的特殊说明

1)DUILIB中并没有 TAB 控件。它的实现方式为:

使用OptionUI即单选框代表TAB选择框,TabLayout代表窗口显示的区域。当Option被选择的时候,调用CTabLayoutUI::Select (index),即可。具体如何操作,请参看示例。

2)DUILIB中并没有单选框。

单选框和复选框都用OPTION表示,当然现在也有了CCheckBoxUI类,但我并不喜欢用,原因是DuiDesigner中并没有提供这个控件,所以我不会使用它,以免造成不必要的麻烦。

区分单选框和复选框主要是靠 Group属性,当指定了Group属性时,这个OPTION就是一个单选框,且所有 Group相同的Option都是同一组,即他们中只有有一个处于选中状态。如果Group为空,那它就是一个复选框。

3)Label显示的文字是单行。Text控件显示的文本是多行。

4)Combox 它的子项设置如下图,designer并没有提供设置项,而且如果你的XML原来有COMBOX的子项设置项,这时候你用designer打开,并进行保存时,你的子项会被删除,所以要注意副本保存工作。

使用 ListLabelElement。

如果使用代码动态添加子项,就要使用类 CListLabelElementUI或是CListLabelContainerUI,前者只是TEXT项,当然可以使用 ShowHtml属性进行图片显示。后者则可以添加多个控件,请试验之。

四、关于BUG。

1.Align属性。

UILabel第181行。代码如下:

if( _tcscmp(pstrName, _T("align")) == 0 ) {
            if( _tcsstr(pstrValue, _T("left")) != NULL ) {
                m_uTextStyle &= ~(DT_CENTER | DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
                m_uTextStyle |= DT_LEFT;
            }
            if( _tcsstr(pstrValue, _T("center")) != NULL ) {
                m_uTextStyle &= ~(DT_LEFT | DT_RIGHT );
                m_uTextStyle |= DT_CENTER;
            }
            if( _tcsstr(pstrValue, _T("right")) != NULL ) {
                m_uTextStyle &= ~(DT_LEFT | DT_CENTER | DT_VCENTER | DT_SINGLELINE);
                m_uTextStyle |= DT_RIGHT;
            }
            if( _tcsstr(pstrValue, _T("top")) != NULL ) {
                m_uTextStyle &= ~(DT_BOTTOM | DT_VCENTER | DT_VCENTER);
                m_uTextStyle |= (DT_TOP | DT_SINGLELINE);
            }
            if( _tcsstr(pstrValue, _T("vcenter")) != NULL ) {
                m_uTextStyle &= ~(DT_TOP | DT_BOTTOM );
                m_uTextStyle |= (DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            }
            if( _tcsstr(pstrValue, _T("bottom")) != NULL ) {
                m_uTextStyle &= ~(DT_TOP | DT_VCENTER | DT_VCENTER);
                m_uTextStyle |= (DT_BOTTOM | DT_SINGLELINE);
            }
        }

我们可以看到,它使用_tcsstr,即字符串查找,所以如果你使用了vcenter后,左、右对齐属性均失效的。所以,显示图片+文字的时候,非常蛋疼的问题来了,文字显示左对齐时,同时也是向上对齐的,它不垂直居中。。。旧版本没有这个问题,这个是新版本改出来的BUG。

2.如果你是手动编写XML,且里面包含中文,一定要将该XML使用UTF-8方式进行保存,否则会遇到类似文字显示不出来的BUG。

3.使用CListUI::SortItems时,如果你使用了自定义参数,会导致崩溃,因为它并没有将你的自定义参数保存,只保存了你的比较函数,如果你在比较函数中使用了自定义参数,很明显会崩溃。

具体代码在 UIList 866行,dwData该参数并未保存。

而在901行的函数ItemComareFunc中,却使用了未初始化的m_compareData。

4.Tree控件,也有BUG。

在 UITreeView.cpp中的31行,看代码:

this->SetFixedHeight(18);
this->SetFixedWidth(250);

很显然,一个TREE_ITEM宽度居然只有250像素,当你的TREE宽度大于250的时候,就会显示该BUG了。

五、当你编写完所有示例之后,就会知道为什么我在上一节中说,为什么一个WND一定要有一个Layout。其具体加载的流程如下:

Root即为第一个 Layout.

我的示例代码:Duilib_test.zip

当然,你一定要熟悉DUILIB中所有DEMO,你不用所有代码都去看过,但一定要知道他们都有些什么功能,当你在项目中遇到相似的情况时,可以从中去找解决方案。

比如,

360中OPTION的应用。

GAME中DEFAULT属性应用,分隔条使用。

QQ有自动换肤、加载ZIP资源代码。

TEST_APP中关于自动布局。。等等。

你一定要过目一遍甚至多遍。

时间: 2024-10-25 07:07:39

Duilib教程-控件练习的相关文章

duilib list控件扩展

对于简单的list控件已经有前辈分析了自带demo的ListRes全过程,duilib DirectUI库里面的一个简单的例子ListDemo, 他分析了listdemo的来龙去脉,这里我只是将个人理解的list分析一下. 由于自带的listdemo不能满足要求,所以必须个人扩展list,通过尝试 发现 1. 列表头禁止拖动情况 这种情况很简单, 配置xml的时候将 表头宽度 和 元素宽度设置相同就行了,listheader布局如下: <List name="domainlist"

修复duilib CEditUI控件和CWebBrowserUI控件中按Tab键无法切换焦点的bug

转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41556615 在duilib中,按tab键会让焦点在Button一类的控件中切换,但是切换焦点一直存在bug,具体的描述如下: 1.在主窗体里弹出新的窗体,当新窗体中存在CEditUI控件并且焦点在此CEditUI控件上,那么按tab键将无法切换焦点而一直处于CEditUI中.(只在新窗体中有此bug,主创体中没有,原因会在后面分析) 2.CWebBrowserUI控件

duilib 时间控件的认识

CDateTimeUI 1.该控件继承了CLabelUI控件,该空间并无重写SetAttribute的函数.全部属性跟CLabelUI控件一样. 2.该控件又有CDateTimeWnd类的一个指针用来显示具体让你选择的时间,该类就是创建的是SysDateTimePick32的控件. 也许会疑惑,为什么Init函数里面的Create没有关于DateTimePick32的相关说明,但是却能创建出这样一个控件.主要要看CWindowWnd::Create函数,该函数的第一个判断语句在GetSuperC

2、duilib 基本控件学习

1.关于创建问题: 在创建窗口的时候 CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); MainWnd* main_wnd = new MainWnd(); main_wnd->Create(NULL, L"Demo2", UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE); main_wnd->CenterWindow(); main_wnd->ShowM

duilib CTileLayoutUI 控件

平铺布局在界面布局里面还是使用的比较多的,CTileLayoutUI继承于CContainerUI , 增加的东西不多,最主要的还是SetPos函数. 通过分析SetPos函数可以得到下面几点: 1.列数自适应 2.子控件高度自适应(每行子控件宽度最高的为基准) 3.子控件宽度至少大于等于子控件宽度 使用就很简单了 ,还是以 listDemo为基础来修改 删除下面这段话 <HorizontalLayout inset="3,0,3,3"> <List name=&qu

Duilib教程-非DUI控件

DUILIB并不是真正的DUI,至少有部分控件不是完全DUI的.其实包括: 1.EDIT. 它的实现原理是,CEditUI包含一个窗口CEditWnd,流程如下: 1)鼠标单击,创建窗口见 EditUI.cpp第217行,在第223行有创建的代码: m_pWindow = new CEditWnd(); ASSERT(m_pWindow); m_pWindow->Init(this); 2)失去焦点时,删除自己,见EditUI.cpp第103行和第131行, LRESULT CEditWnd::

Duilib中为RichEdit\Edit控件添加自定义右键菜单

前言 Duilib中的RichEdit控件在使用中发现,基本上对复制.粘贴.剪切等快捷方式都是支持的,不过唯一缺点是没有右键菜单,感觉不够好,于是就想着加上右键菜单. 右键菜单基本思路是,在RichEdit的消息处理函数中对鼠标的右键消息处理,发送一个自定义的Notify消息出来,主窗口中受到这个消息后弹出自己的右键菜单. 实现方法 第一步:把鼠标右键消息转发出来 MessageHandler中修改原有代码 bool bWasHandled = true; if( (uMsg >= WM_MOU

分享个Duilib中基于wke的浏览器控件

概述 wke是基于谷歌chrome浏览器源代码的裁剪版本,大小仅仅只有10M左右,无需依赖其他的扩展库(跟CEF的一大堆大约40M的DLL来比简直爽呆了),就可以在本地使用谷歌内核快速加载网页.网上也有基于wke在Duilib 上扩展的控件代码,其实wke头文件挺清楚的了,接口一目了然,特别是JS与C++交互的函数更是容易看懂,也没什么难的,你也可以做到的. 代码 毕竟是裁剪库,有的功能还是没有接口来处理的(比如网页加载前.页面跳转.菜单消息--),头文件代码: #ifndef __UIWKEW

Duilib中带有权重的灵活控件排列实现(一)

在开发播放器软件过程中,因为窗口的大小是可变的,为了让控制栏部分的控件(播放,上一集,下一集,全屏,字幕等)适应窗口的尺寸的变化而显示隐藏,产品经理会定义一系列的规则,好让在任何时候都最核心的功能提供给用户使用. 先列一下产品经理给予的需求: 两边往中间缩,保证左侧LOGO和右侧X最优先显示. 顶部隐藏优先级:搜索栏,换肤,意见反馈,播放记录,最小化,最大化 底部隐藏优先级:全屏,画质增强,无痕,打开文件,播放顺序,音量条 在处理这个需求过程中,前人也尝试了一些方法,比较通过全float绝对布局