轉載請說明原出處,謝謝~·http://blog.csdn.net/zhuhongshu/article/details/45362751
#ifndef SKIN_PICKER_PICTURE_ITEM_H
#define SKIN_PICKER_PICTURE_ITEM_H
//xml sample:<SkinPikerPictureItem name="" width="118" height="70" bkimage="UI\BKImage\1small.jpg" bkname="測試" author="Redrain" />
//類名和接口名,在CreateControl函數中會用到
const TCHAR kSkinPickerPictureItemClassName[] = _T("SkinPikerPictureItemUI");
const TCHAR kSkinPickerPictureItemInterface[] = _T("SkinPikerPictureItem");
//黑色的前景圖的位置
const TCHAR kSkinPickerPictureItemForeImage[] = _T("file='UI\\LeftTab\\listitem\\ListBk.png' fade='150'");
//邊框的顏色、圖片名稱的文字顏色、作者信息的文字顏色
const DWORD kBorderColor = 0xFF64B0FA;
const DWORD kBkNameColor = 0xFFFFFFFF;
const DWORD kAuthorColor = 0xFFAAAAAA;
class CSkinPikerPictureItemUI : public CButtonUI
{
public:
CSkinPikerPictureItemUI();
LPCTSTR GetClass() const;
LPVOID GetInterface(LPCTSTR pstrName);
void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
void PaintStatusImage(HDC hDC);
private:
CDuiString m_BkName;
CDuiString m_Author;
};
#endif // SKIN_PICKER_PICTURE_ITEM_H
CSkinPikerPictureItemUI::CSkinPikerPictureItemUI()
{
m_Author = _T("作者:");
}
LPCTSTR CSkinPikerPictureItemUI::GetClass() const
{
return kSkinPickerPictureItemClassName;
}
LPVOID CSkinPikerPictureItemUI::GetInterface(LPCTSTR pstrName)
{
if( _tcscmp(pstrName, kSkinPickerPictureItemInterface) == 0 ) return static_cast<CSkinPikerPictureItemUI*>(this);
return CButtonUI::GetInterface(pstrName);
}
void CSkinPikerPictureItemUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
if( _tcscmp(pstrName, _T("bkname")) == 0 ) m_BkName = pstrValue;
else if( _tcscmp(pstrName, _T("author")) == 0 ) m_Author += pstrValue;
CButtonUI::SetAttribute(pstrName, pstrValue);
}
void CSkinPikerPictureItemUI::PaintStatusImage(HDC hDC)
{
CButtonUI::PaintStatusImage(hDC);
if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
else m_uButtonState &= ~ UISTATE_FOCUSED;
if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
else m_uButtonState &= ~ UISTATE_DISABLED;
if( (m_uButtonState & UISTATE_PUSHED) != 0 || (m_uButtonState & UISTATE_HOT) != 0) {
DrawImage(hDC, kSkinPickerPictureItemForeImage) ;
//計算作者信息文字和背景圖片名字文字的顯示位置,這裏是用了硬編碼,請使用者自己修改
RECT rcBkName = m_rcItem;
LONG nTextPadding = (m_rcItem.right - m_rcItem.left - CRenderEngine::GetTextSize(hDC, GetManager(),\
m_BkName.GetData(), m_iFont, m_uTextStyle).cx) / 2;
rcBkName.left += nTextPadding;
rcBkName.right -= nTextPadding;
rcBkName.top += 15;
rcBkName.bottom = rcBkName.top + 20;
RECT rcAuthor = m_rcItem;
nTextPadding = (m_rcItem.right - m_rcItem.left - CRenderEngine::GetTextSize(hDC, GetManager(),\
m_Author.GetData(), m_iFont, m_uTextStyle).cx) / 2;
rcAuthor.left += nTextPadding;
rcAuthor.right -= nTextPadding;
rcAuthor.top += 40;
rcAuthor.bottom = rcAuthor.top + 20;
CRenderEngine::DrawText(hDC, m_pManager, rcBkName, m_BkName, kBkNameColor, m_iFont, m_uTextStyle);
CRenderEngine::DrawText(hDC, m_pManager, rcAuthor, m_Author, kAuthorColor, m_iFont, m_uTextStyle);
CRenderEngine::DrawRect(hDC, m_rcItem, 2, kBorderColor);
}
}
新的控件名爲CSkinPickerPictureItemUI。一般來說,建立新控件後,最先應該重寫的兩個函數是GetClass和GetInterface。他們後用來區分控件的類型的虛函數,用於動態識別控件類型和做控件的類型轉換。
virtual void DoEvent(TEventUI& event);
virtual void DoPaint(HDC hDC, const RECT& rcPaint);
virtual void PaintBkColor(HDC hDC);
virtual void PaintBkImage(HDC hDC);
virtual void PaintStatusImage(HDC hDC);
virtual void PaintText(HDC hDC);
virtual void PaintBorder(HDC hDC);
virtual void DoInit();
virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
virtual bool IsVisible() const;
virtual void SetVisible(bool bVisible = true);
virtual void SetInternVisible(bool bVisible = true); // 僅供內部調用,有些UI擁有窗口句柄,需要重寫此函數
virtual void SetPos(RECT rc);
CControlUI* CSkinPickerDialog::CreateControl(LPCTSTR pstrClass)
{
if (_tcsicmp(pstrClass, kSkinPickerPictureItemInterface) == 0)
return new CSkinPikerPictureItemUI();
return NULL;
}
CControlUI* CDialogBuilder::Create(STRINGorID xml, LPCTSTR type, IDialogBuilderCallback* pCallback,
CPaintManagerUI* pManager, CControlUI* pParent)
這個函數 的第一個參數指定爲xml文件的路徑;第二個參數一般指定爲NULL,我這裏不詳解了;第三個參數,就是識別自定義控件的關鍵了,這個參數要指定爲繼承了IDialogBuilderCallback接口的類對象的指針,比如窗體類繼承IDialogBuilderCallback,這個參數就填寫窗體類對象的指針。只有填寫了這個參數,自定義控件纔會被識別,經常有人問自己的自定義控件爲什麼無法被識別。多數情況就是這裏沒處理好;第四個參數指定CPaintManagerUI類對象指針,這個肯定會伴隨着窗體類對象一起存在。最後一個參數一般爲NULL。
m_hhWnd = CreateWindow(_T("#32770"), _T("WndMediaDisplay"), WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, m_PaintManager.GetPaintWindow(), (HMENU)0, NULL, NULL);
LPCTSTR GetWindowClassName() const;
LPCTSTR GetSuperClassName() const;