Duilib教程-控件练习

1、控件消息的响应。css

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

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

而后在 CHelloDuilibWnd 中重载 WindowImplBase::Notify ();函数

代码以下:布局

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

 

如是便可退出程序。学习

 

2、获取XML中的控件ui

通常的状况下,能够在窗口初始化的时候获取一个控件,固然你在何时获取都是能够的,在初始化获取,之后你就能够任意地使用了。this

添加剧载函数:WindowImplBae::InitWindow,代码以下:spa

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

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

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

 

3、标题栏

窗口有一个属性 caption 指定了窗口标题栏的位置。默认0表明了窗口的最大值。好比说,咱们想要标题栏高度为30像素,便可设为:(0,0,0,30)left, top, right都为0,只有bottom30right0表示为最右边。固然若是所有设为0,会被认为没有标题栏。

 

4、示例程序的练习。

在这里,我并不会为你介绍全部控件的编写,只是做一个简单的介绍,而后控件的编写还须要你本身动手,只有本身写过的代码才是掌握了的代码。若是以天天学一个控件的效率的话,大概顶多两周即基本掌握全部控件的写法。下面是我之前学习的一个例子,截图以下,最后我也会附件贴上,但愿对您的学习有所帮助。

固然我并无编写全部的控件,好比menuprogressbarsliderbartree等控件,这个示例是很久之前写的了。

 

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

 

其它控件亦是如此。

 

1.控件的基本属性:

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

2)Text, 标题

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

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

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

 

关于float及 Layout 的 insertchildpaddinghscrollbarvscrollbar等属性,我会在自动布局中进行说明。

 

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属性进行图片显示。后者则能够添加多个控件,请试验之。

 

4、关于BUG

1.Align属性。

UILabel181行。代码以下:

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了。

 

5、当你编写完全部示例以后,就会知道为何我在上一节中说,为何一个WND必定要有一个Layout。其具体加载的流程以下:

 

Root即为第一个 Layout.

 

个人示例代码:Duilib_test.zip

固然,你必定要熟悉DUILIB中全部DEMO,你不用全部代码都去看过,但必定要知道他们都有些什么功能,当你在项目中遇到类似的状况时,能够从中去找解决方案。

好比,

360中OPTION的应用。

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

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

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

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