源码下载地址:https://gitee.com/Ailsc/Duilib

Duilib list 表头增加控件,通过观察发现凡是想把某控件Add到某一控件(父控件)上面,则父控件必须由CContainerUI派生,然后我们观察一下CListHeaderItem的实现,发现对于继承的接口我们即使修改为CContainerUI下面继承的接口完全没有问题,所以我们试着把CListHeaderItemUI 修改为:

class UILIB_API CListHeaderItemUI : public CContainerUI/*CControlUI*/,并且CListHeaderItemUI 内部所有的 Control::xx 全部修改为 __super::xx 此时我们不妨测试一下,在表头增加checkBox,看看结果:

Duilib list表头增加增加控件_sed

源码:*.h

class UILIB_API CListHeaderItemUI : <span ><strong>public CContainerUI</strong></span>/*CControlUI*/
{
public:
CListHeaderItemUI();

LPCTSTR GetClass() const;
LPVOID GetInterface(LPCTSTR pstrName);
UINT GetControlFlags() const;

void SetEnabled(bool bEnable = true);

bool IsDragable() const;
void SetDragable(bool bDragable);
DWORD GetSepWidth() const;
void SetSepWidth(int iWidth);
DWORD GetTextStyle() const;
void SetTextStyle(UINT uStyle);
DWORD GetTextColor() const;
void SetTextColor(DWORD dwTextColor);
void SetTextPadding(RECT rc);
RECT GetTextPadding() const;
void SetFont(int index);
bool IsShowHtml();
void SetShowHtml(bool bShowHtml = true);
LPCTSTR GetNormalImage() const;
void SetNormalImage(LPCTSTR pStrImage);
LPCTSTR GetHotImage() const;
void SetHotImage(LPCTSTR pStrImage);
LPCTSTR GetPushedImage() const;
void SetPushedImage(LPCTSTR pStrImage);
LPCTSTR GetFocusedImage() const;
void SetFocusedImage(LPCTSTR pStrImage);
LPCTSTR GetSepImage() const;
void SetSepImage(LPCTSTR pStrImage);

void DoEvent(TEventUI& event);
SIZE EstimateSize(SIZE szAvailable);
void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
RECT GetThumbRect() const;

void PaintText(HDC hDC);
void PaintStatusImage(HDC hDC);

protected:
POINT ptLastMouse;
bool m_bDragable;
UINT m_uButtonState;
int m_iSepWidth;
DWORD m_dwTextColor;
int m_iFont;
UINT m_uTextStyle;
bool m_bShowHtml;
RECT m_rcTextPadding;
CDuiString m_sNormalImage;
CDuiString m_sHotImage;
CDuiString m_sPushedImage;
CDuiString m_sFocusedImage;
CDuiString m_sSepImage;
CDuiString m_sSepImageModify;
};

继承返回修改 __super  *.cpp

CListHeaderItemUI::CListHeaderItemUI() : m_bDragable(true), m_uButtonState(0), m_iSepWidth(4),
m_uTextStyle(DT_VCENTER | DT_CENTER | DT_SINGLELINE), m_dwTextColor(0), m_iFont(-1), m_bShowHtml(false)
{
SetTextPadding(CDuiRect(2, 0, 2, 0));
ptLastMouse.x = ptLastMouse.y = 0;
SetMinWidth(16);
}

LPCTSTR CListHeaderItemUI::GetClass() const
{
return _T("ListHeaderItemUI");
}

LPVOID CListHeaderItemUI::GetInterface(LPCTSTR pstrName)
{
if( _tcscmp(pstrName, DUI_CTR_LISTHEADERITEM) == 0 ) return this;
return <span ><strong>__super::GetInterface(pstrName);</strong></span>
}

UINT CListHeaderItemUI::GetControlFlags() const
{
if( IsEnabled() && m_iSepWidth != 0 ) return UIFLAG_SETCURSOR;
else return 0;
}

void CListHeaderItemUI::SetEnabled(bool bEnable)
{
<span ><strong>__super::SetEnabled(bEnable);</strong></span>
if( !IsEnabled() ) {
m_uButtonState = 0;
}
}

bool CListHeaderItemUI::IsDragable() const
{
return m_bDragable;
}

void CListHeaderItemUI::SetDragable(bool bDragable)
{
m_bDragable = bDragable;
if ( !m_bDragable ) m_uButtonState &= ~UISTATE_CAPTURED;
}

DWORD CListHeaderItemUI::GetSepWidth() const
{
return m_iSepWidth;
}

void CListHeaderItemUI::SetSepWidth(int iWidth)
{
m_iSepWidth = iWidth;
}

DWORD CListHeaderItemUI::GetTextStyle() const
{
return m_uTextStyle;
}

void CListHeaderItemUI::SetTextStyle(UINT uStyle)
{
m_uTextStyle = uStyle;
Invalidate();
}

DWORD CListHeaderItemUI::GetTextColor() const
{
return m_dwTextColor;
}


void CListHeaderItemUI::SetTextColor(DWORD dwTextColor)
{
m_dwTextColor = dwTextColor;
}

RECT CListHeaderItemUI::GetTextPadding() const
{
return m_rcTextPadding;
}

void CListHeaderItemUI::SetTextPadding(RECT rc)
{
m_rcTextPadding = rc;
Invalidate();
}

void CListHeaderItemUI::SetFont(int index)
{
m_iFont = index;
}

bool CListHeaderItemUI::IsShowHtml()
{
return m_bShowHtml;
}

void CListHeaderItemUI::SetShowHtml(bool bShowHtml)
{
if( m_bShowHtml == bShowHtml ) return;

m_bShowHtml = bShowHtml;
Invalidate();
}

LPCTSTR CListHeaderItemUI::GetNormalImage() const
{
return m_sNormalImage;
}

void CListHeaderItemUI::SetNormalImage(LPCTSTR pStrImage)
{
m_sNormalImage = pStrImage;
Invalidate();
}

LPCTSTR CListHeaderItemUI::GetHotImage() const
{
return m_sHotImage;
}

void CListHeaderItemUI::SetHotImage(LPCTSTR pStrImage)
{
m_sHotImage = pStrImage;
Invalidate();
}

LPCTSTR CListHeaderItemUI::GetPushedImage() const
{
return m_sPushedImage;
}

void CListHeaderItemUI::SetPushedImage(LPCTSTR pStrImage)
{
m_sPushedImage = pStrImage;
Invalidate();
}

LPCTSTR CListHeaderItemUI::GetFocusedImage() const
{
return m_sFocusedImage;
}

void CListHeaderItemUI::SetFocusedImage(LPCTSTR pStrImage)
{
m_sFocusedImage = pStrImage;
Invalidate();
}

LPCTSTR CListHeaderItemUI::GetSepImage() const
{
return m_sSepImage;
}

void CListHeaderItemUI::SetSepImage(LPCTSTR pStrImage)
{
m_sSepImage = pStrImage;
Invalidate();
}

void CListHeaderItemUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
if( _tcscmp(pstrName, _T("dragable")) == 0 ) SetDragable(_tcscmp(pstrValue, _T("true")) == 0);
else if( _tcscmp(pstrName, _T("sepwidth")) == 0 ) SetSepWidth(_ttoi(pstrValue));
else if( _tcscmp(pstrName, _T("align")) == 0 ) {
if( _tcsstr(pstrValue, _T("left")) != NULL ) {
m_uTextStyle &= ~(DT_CENTER | DT_RIGHT);
m_uTextStyle |= DT_LEFT;
}
if( _tcsstr(pstrValue, _T("center")) != NULL ) {
m_uTextStyle &= ~(DT_LEFT | DT_RIGHT);
m_uTextStyle |= DT_CENTER;
}
if( _tcsstr(pstrValue, _T("right")) != NULL ) {
m_uTextStyle &= ~(DT_LEFT | DT_CENTER);
m_uTextStyle |= DT_RIGHT;
}
}
else if( _tcscmp(pstrName, _T("endellipsis")) == 0 ) {
if( _tcscmp(pstrValue, _T("true")) == 0 ) m_uTextStyle |= DT_END_ELLIPSIS;
else m_uTextStyle &= ~DT_END_ELLIPSIS;
}
else if( _tcscmp(pstrName, _T("font")) == 0 ) SetFont(_ttoi(pstrValue));
else if( _tcscmp(pstrName, _T("textcolor")) == 0 ) {
if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
LPTSTR pstr = NULL;
DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
SetTextColor(clrColor);
}
else if( _tcscmp(pstrName, _T("textpadding")) == 0 ) {
RECT rcTextPadding = { 0 };
LPTSTR pstr = NULL;
rcTextPadding.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
rcTextPadding.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
rcTextPadding.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
rcTextPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
SetTextPadding(rcTextPadding);
}
else if( _tcscmp(pstrName, _T("showhtml")) == 0 ) SetShowHtml(_tcscmp(pstrValue, _T("true")) == 0);
else if( _tcscmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
else if( _tcscmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
else if( _tcscmp(pstrName, _T("pushedimage")) == 0 ) SetPushedImage(pstrValue);
else if( _tcscmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
else if( _tcscmp(pstrName, _T("sepimage")) == 0 ) SetSepImage(pstrValue);
else <strong><span >__super::SetAttribute(pstrName, pstrValue);</span></strong>
}

void CListHeaderItemUI::DoEvent(TEventUI& event)
{
if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
if( m_pParent != NULL ) m_pParent->DoEvent(event);
else <span ><strong>__super::DoEvent(event);</strong></span>
return;
}

if( event.Type == UIEVENT_SETFOCUS )
{
Invalidate();
}
if( event.Type == UIEVENT_KILLFOCUS )
{
Invalidate();
}
if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
{
if( !IsEnabled() ) return;
RECT rcSeparator = GetThumbRect();
if (m_iSepWidth>=0)//111024 by cddjr, 增加分隔符区域,方便用户拖动
rcSeparator.left-=4;
else
rcSeparator.right+=4;
if( ::PtInRect(&rcSeparator, event.ptMouse) ) {
if( m_bDragable ) {
m_uButtonState |= UISTATE_CAPTURED;
ptLastMouse = event.ptMouse;
}
}
else {
m_uButtonState |= UISTATE_PUSHED;
m_pManager->SendNotify(this, DUI_MSGTYPE_HEADERCLICK);
Invalidate();
}
return;
}
if( event.Type == UIEVENT_BUTTONUP )
{
if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
m_uButtonState &= ~UISTATE_CAPTURED;
if( GetParent() )
GetParent()->NeedParentUpdate();
}
else if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
m_uButtonState &= ~UISTATE_PUSHED;
Invalidate();
}
return;
}
if( event.Type == UIEVENT_MOUSEMOVE )
{
if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
RECT rc = m_rcItem;
if( m_iSepWidth >= 0 ) {
rc.right -= ptLastMouse.x - event.ptMouse.x;
}
else {
rc.left -= ptLastMouse.x - event.ptMouse.x;
}

if( rc.right - rc.left > GetMinWidth() ) {
m_cxyFixed.cx = rc.right - rc.left;
ptLastMouse = event.ptMouse;
if( GetParent() )
GetParent()->NeedParentUpdate();
}
}
return;
}
if( event.Type == UIEVENT_SETCURSOR )
{
RECT rcSeparator = GetThumbRect();
if (m_iSepWidth>=0)//111024 by cddjr, 增加分隔符区域,方便用户拖动
rcSeparator.left-=4;
else
rcSeparator.right+=4;
if( IsEnabled() && m_bDragable && ::PtInRect(&rcSeparator, event.ptMouse) ) {
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
return;
}
}
if( event.Type == UIEVENT_MOUSEENTER )
{
if( IsEnabled() ) {
m_uButtonState |= UISTATE_HOT;
Invalidate();
}
return;
}
if( event.Type == UIEVENT_MOUSELEAVE )
{
if( IsEnabled() ) {
m_uButtonState &= ~UISTATE_HOT;
Invalidate();
}
return;
}
<span ><strong>__super::DoEvent(event);</strong></span>
}

SIZE CListHeaderItemUI::EstimateSize(SIZE szAvailable)
{
if( m_cxyFixed.cy == 0 ) return CSize(m_cxyFixed.cx, m_pManager->GetDefaultFontInfo()->tm.tmHeight + 14);
return <span ><strong>__super::EstimateSize(szAvailable);</strong></span>
}

RECT CListHeaderItemUI::GetThumbRect() const
{
if( m_iSepWidth >= 0 ) return CDuiRect(m_rcItem.right - m_iSepWidth, m_rcItem.top, m_rcItem.right, m_rcItem.bottom);
else return CDuiRect(m_rcItem.left, m_rcItem.top, m_rcItem.left - m_iSepWidth, m_rcItem.bottom);
}

void CListHeaderItemUI::PaintStatusImage(HDC hDC)
{
if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
else m_uButtonState &= ~ UISTATE_FOCUSED;

if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
if( m_sPushedImage.IsEmpty() && !m_sNormalImage.IsEmpty() ) DrawImage(hDC, (LPCTSTR)m_sNormalImage);
if( !DrawImage(hDC, (LPCTSTR)m_sPushedImage) ) m_sPushedImage.Empty();
}
else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
if( m_sHotImage.IsEmpty() && !m_sNormalImage.IsEmpty() ) DrawImage(hDC, (LPCTSTR)m_sNormalImage);
if( !DrawImage(hDC, (LPCTSTR)m_sHotImage) ) m_sHotImage.Empty();
}
else if( (m_uButtonState & UISTATE_FOCUSED) != 0 ) {
if( m_sFocusedImage.IsEmpty() && !m_sNormalImage.IsEmpty() ) DrawImage(hDC, (LPCTSTR)m_sNormalImage);
if( !DrawImage(hDC, (LPCTSTR)m_sFocusedImage) ) m_sFocusedImage.Empty();
}
else {
if( !m_sNormalImage.IsEmpty() ) {
if( !DrawImage(hDC, (LPCTSTR)m_sNormalImage) ) m_sNormalImage.Empty();
}
}

if( !m_sSepImage.IsEmpty() ) {
RECT rcThumb = GetThumbRect();
rcThumb.left -= m_rcItem.left;
rcThumb.top -= m_rcItem.top;
rcThumb.right -= m_rcItem.left;
rcThumb.bottom -= m_rcItem.top;

m_sSepImageModify.Empty();
m_sSepImageModify.SmallFormat(_T("dest='%d,%d,%d,%d'"), rcThumb.left, rcThumb.top, rcThumb.right, rcThumb.bottom);
if( !DrawImage(hDC, (LPCTSTR)m_sSepImage, (LPCTSTR)m_sSepImageModify) ) m_sSepImage.Empty();
}
}

void CListHeaderItemUI::PaintText(HDC hDC)
{
if( m_dwTextColor == 0 ) m_dwTextColor = m_pManager->GetDefaultFontColor();

RECT rcText = m_rcItem;
rcText.left += m_rcTextPadding.left;
rcText.top += m_rcTextPadding.top;
rcText.right -= m_rcTextPadding.right;
rcText.bottom -= m_rcTextPadding.bottom;

if( m_sText.IsEmpty() ) return;
int nLinks = 0;
if( m_bShowHtml )
CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, m_sText, m_dwTextColor, \
NULL, NULL, nLinks, DT_SINGLELINE | m_uTextStyle);
else
CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, m_dwTextColor, \
m_iFont, DT_SINGLELINE | m_uTextStyle);
}