转载请说明原出处,谢谢~・http://blog.csdn.net/zhuhongshu/article/details/45362751


#define SKIN_PICKER_PICTURE_ITEM_H
//xml sample:<SkinPikerPictureItem name="" width="118" height="70" bkimage="UIBKImage1small.jpg" bkname="测试" author="Redrain" />
//类名和接口名,在CreateControl函数中会用到
const TCHAR kSkinPickerPictureItemClassName[] = _T("SkinPikerPictureItemUI");
const TCHAR kSkinPickerPictureItemInterface[] = _T("SkinPikerPictureItem");
//黑色的前景图的位置
const TCHAR kSkinPickerPictureItemForeImage[] = _T("file='UILeftTablistitemListBk.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
{
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。1般来讲,建立新控件后,最早应当重写的两个函数是GetClass和GetInterface。他们后用来辨别控件的类型的虚函数,用于动态辨认控件类型和做控件的类型转换。
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);
以上列出的函数,是最常被重写的。
{
if (_tcsicmp(pstrClass, kSkinPickerPictureItemInterface) == 0)
return new CSkinPikerPictureItemUI();
return NULL;
}
CPaintManagerUI* pManager, CControlUI* pParent)
这个函数 的第1个参数指定为xml文件的路径;第2个参数1般指定为NULL,我这里不详解了;第3个参数,就是辨认自定义控件的关键了,这个参数要指定为继承了IDialogBuilderCallback接口的类对象的指针,比如窗体类继承IDialogBuilderCallback,这个参数就填写窗体类对象的指针。只有填写了这个参数,自定义控件才会被辨认,常常有人问自己的自定义控件为何没法被辨认。多数情况就是这里没处理好;第4个参数指定CPaintManagerUI类对象指针,这个肯定会伴随着窗体类对象1起存在。最后1个参数1般为NULL。
然后在SetVisible等函数内控制子窗体的显示隐藏;在SetPos函数内控制子窗体的位置、限制在本控件的范围内。
波比源码 » [置顶] duilib开发基础:创建自定义控件的过程