DXUTGUI控件的定制(三)

    <!--版权所有foruok,转载请注明出处!!-->

    定制控件

     DXUTGUI的控件库默认使用内置的纹理资源,这个纹理资源可以在CDXUTDialog的Init函数中指定为我们自己的纹理资源(通常可以用一个图片文件来替代)。在这个系列的 第一篇中,介绍了如何使用自己的纹理资源改变整个控件库的风格。    研究CDXUTDialog的InitDefaultElements函数可以发现,DXUTGUI为每种控件定义了若干元素,这些元素保存在m_DefaultElements数组中。当增加一个新的控件时,比较控件类型,将该类型的元素集从DefaultElements取出,传递给该控件,该控件生成自己的元素实例并保存起来。这一点事实支持 第二篇中提供的修改某个控件和某类控件外观的办法。    我们发现纹理资源保存在CDXUTDialogResourceManager的成员变量m_TextureCache中。m_TextureCache是一个动态数组,可以保存任意的纹理资源,如一个按钮的图片纹理,一个列表框的背景纹理等。只需要调用CDXUTDialg::SetTexture函数,指定一个ID和纹理文件名即可。    纹理有了保存的地方,接下来只需要让控件使用我们自己的纹理就可以进行定制了。而控件的定制分为三类:单个控件的定制、一类控件的定制、生成新控件类型。下面一一说明怎么来实现。

    一、单个控件定制

    单个控件的定制比较简单,以按钮为例,需要三步:    (1)CDXUTDialog::AddButton生成按钮pBtn    (2)CDXUTDialog::SetTexture,生成该按钮的纹理,记录纹理序号nTexture    (3)pBtn->GetElement获取CDXUTElement指针pElem,pElem->SetTexture修改该控件所用纹理为nTexture。    上面的定制受限于DXUTGUI,需要根据其所实现的控件的渲染方法来生成自己的纹理资源,还要查看InitDefaultElements来决定怎么调用CDXUTElement::SetTexture和CDXUTElement::SetFont。

    二、单类控件的定制

    某一类控件的定制需要更改该类控件的默认元素,这个可以通过CDXUTDialog::SetDefaultElement来实现。需要两步完成:    (1)CDXUTDialog::SetTexture,生成该类控件的纹理,记录纹理序号nTexture    (2)CDXUTDialog::GetDefaultElement或者默认元素对象的指针pElem,然后pElem->SetTexture修改。    第(2)步也还有另一种实现方法。声明CDXUTElement对象,设置其成员,然后调用CDXUTDialog::SetDefaultElement,改写初始化时生成的默认元素集。无论怎样,都需要了解InitDefaultElements函数中做了什么。

    三、生成新控件类型

    生成新控件并使用定制的纹理,需要以下几步:    (1)实现控件类    (2)加载资源    (3)为新类型控件生成默认元素集    (4)生成控件实例,添加到对话框    我们不改变DXUT自己的文件,一切都在我们自己的文件中实现。    (1)DXUTGUI提供的控件不一定能满足我们需要,有时候需要自己实现新的控件,如图片按钮。我们可以从CDXUTControl派生,也可以从某个特定的控件类派生。下面我们以图片按钮的实现为例来说明,先看代码。   
class  CDXUTImageButton : public  CDXUTButton {public:    CDXUTImageButton(CDXUTDialog *pDialog = NULL ):CDXUTButton(pDialog)    {        m_Type = (DXUT_CONTROL_TYPE)(DXUT_CONTROL_SCROLLBAR + 1);    };    ~CDXUTImageButton(void){};    virtual void Render( float fElapsedTime )    {        int nOffsetX = 0;    int nOffsetY = 0;    DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;    int iIndex = 0;    if( m_bVisible == false )    {        iState = DXUT_STATE_HIDDEN;    }    else if( m_bEnabled == false )    {        iState = DXUT_STATE_DISABLED;        iIndex = 2;    }    else if( m_bPressed )    {        iState = DXUT_STATE_PRESSED;        iIndex = 1;    }    else if( m_bMouseOver )    {        iState = DXUT_STATE_MOUSEOVER;        iIndex = 3;    }    else if( m_bHasFocus )    {        iState = DXUT_STATE_FOCUS;        iIndex = 3;    }    // Main button    CDXUTElement *pElement = m_Elements.GetAt( iIndex );    float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;    // Blend current color    pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );     m_pDialog->DrawSprite( pElement, &m_rcBoundingBox, 0.8f );};
    我们需要为CDXUTImageButton指定一个控件类型,取 DXUT_CONTROL_SCROLLBAR + 1。同时改写CDXUTButton的Render函数,依据按钮状态取不同的纹理元素进行绘制。我们所提供的图片具有四个状态(顺序):正常态、 下压态、禁止态、 悬停态,对应按钮的四个状态。    (2)有了图片按钮类,我们需要将按钮的资源加载进来。可以用CDXUTDialog::SetTexture实现。    (3)四次调用CDXUTDialog::SetDefaultElement,为图片按钮设置四个元素。    (4)分配CDXUTImageButton对象,调用CDXUTDialog::AddControl,然后设置该按钮的ID、TEXT、位置、大小等元素。    (2)、(3)、(4)步的示例代码:
     // init custom button, normal way      int  iTexture  =  g_SampleUI.SetTexture(IDC_BUTTON_CUSTOM_1, L " play.tga " );    CDXUTElement elem;    elem.iTexture  =  IDC_BUTTON_CUSTOM_1;    elem.iFont  =   0 ;    RECT rc  =   {0} ;     for ( int  i = 0 ; i < 4 ; i ++ )     {        SetRect(&rc, i*640, (i+1)*6428);        elem.SetTexture(IDC_BUTTON_CUSTOM_1, &rc, D3DCOLOR_ARGB(128255255255));        g_SampleUI.SetDefaultElement(DXUT_CONTROL_SCROLLBAR+1, i, &elem);    }     CDXUTImageButton  * imgbtn  =   new  CDXUTImageButton( & g_SampleUI);    g_SampleUI.AddControl(imgbtn);    imgbtn -> SetID(IDC_BUTTON_CUSTOM_1);    imgbtn -> SetText(L " CustomStyle " );    imgbtn -> SetSize( 64 27 );    imgbtn -> SetLocation( 5 5 );
        如果改动DXUTGUI的源码,则可以在枚举类型DXUT_CONTROL_TYPE中添加DXUT_CONTROL_IMAGEBUTTON项,同时将上面的for循环设置默认元素集部分加入到InitDefaultElements函数中,给CDXUTDialog添加AddImageButton函数。那么生成按钮的代码看起来会相对简洁一些,它可能是这个样子:
g_SampleUI.AddImageButton(IDC_BUTTON_CUSTOM_1, L " CustomStyle " 5 , 5,  64 27 );
    好了,DXUTGUI控件定制到此为止。     <!--版权所有foruok,转载请注明出处!!-->
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

foruok

你可以选择打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值