DXUTGUI控件的定制(三)
系統
2172 0
<!--版權所有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
);
}
;
我們需要為CDXUTImageButton指定一個控件類型,取
DXUT_CONTROL_SCROLLBAR
+
1
。同時改寫CDXUTButton的Render函數,依據按鈕狀態取不同的紋理元素進行繪制。我們所提供的圖片具有四個狀態(順序):正常態、
下壓態、禁止態、
懸停態,對應按鈕的四個狀態。 (2)有了圖片按鈕類,我們需要將按鈕的資源加載進來。可以用CDXUTDialog::SetTexture實現。 (3)四次調用CDXUTDialog::SetDefaultElement,為圖片按鈕設置四個元素。 (4)分配CDXUTImageButton對象,調用CDXUTDialog::AddControl,然后設置該按鈕的ID、TEXT、位置、大小等元素。 (2)、(3)、(4)步的示例代碼:
//
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
);
如果改動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,轉載請注明出處!!-->
DXUTGUI控件的定制(三)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元