<!--版权所有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_STATEiState
=
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
;
}
//
Mainbutton
CDXUTElement
*
pElement
=
m_Elements.GetAt(iIndex);
float
fBlendRate
=
(iState
==
DXUT_STATE_PRESSED)
?
0.0f
:
0.8f
;
//
Blendcurrentcolor
pElement
->
TextureColor.Blend(iState,fElapsedTime,fBlendRate);
m_pDialog
->
DrawSprite(pElement,
&
m_rcBoundingBox,
0.8f
);
}
;
//
initcustombutton,normalway
int
iTexture
=
g_SampleUI.SetTexture(IDC_BUTTON_CUSTOM_1,L
"
play.tga
"
);
CDXUTElementelem;
elem.iTexture
=
IDC_BUTTON_CUSTOM_1;
elem.iFont
=
0
;
RECTrc
=
{
0
}
;
for
(
int
i
=
0
;i
<
4
;i
++
)
{
SetRect(
&
rc,i
*
64
,
0
,(i
+
1
)
*
64
,
28
);
elem.SetTexture(IDC_BUTTON_CUSTOM_1,
&
rc,D3DCOLOR_ARGB(
128
,
255
,
255
,
255
));
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
);
g_SampleUI.AddImageButton(IDC_BUTTON_CUSTOM_1,L
"
CustomStyle
"
,
5
, 5,
64
,
27
);