#include "stdafx.h"
#include "UIListEx.h"

namespace DuiLib {

	/////////////////////////////////////////////////////////////////////////////////////
	//
	//
	IMPLEMENT_DUICONTROL(CListExUI)

	CListExUI::CListExUI() : m_pEditUI(NULL), m_pComboBoxUI(NULL), m_bAddMessageFilter(FALSE),m_nRow(-1),m_nColum(-1),m_pXCallback(NULL)
	{
	}

	LPCTSTR CListExUI::GetClass() const
	{
		return _T("XListUI");
	}

	UINT CListExUI::GetControlFlags() const
	{
		return UIFLAG_TABSTOP;
	}

	LPVOID CListExUI::GetInterface(LPCTSTR pstrName)
	{
		if( _tcsicmp(pstrName, _T("ListEx")) == 0 ) return static_cast<IListOwnerUI*>(this);
		return CListUI::GetInterface(pstrName);
	}
	BOOL CListExUI::CheckColumEditable(int nColum)
	{
		CListContainerHeaderItemUI* pHItem = static_cast<CListContainerHeaderItemUI*>(m_pHeader->GetItemAt(nColum));
		return pHItem != NULL? pHItem->GetColumeEditable() : FALSE;
	}
	void CListExUI::InitListCtrl()
	{
		if (!m_bAddMessageFilter)
		{
			GetManager()->AddNotifier(this);
			m_bAddMessageFilter = TRUE;
		}
	}
	CRichEditUI* CListExUI::GetEditUI()
	{
		if (m_pEditUI == NULL)
		{
			m_pEditUI = new CRichEditUI;
			m_pEditUI->SetName(_T("ListEx_Edit"));
			LPCTSTR pDefaultAttributes = GetManager()->GetDefaultAttributeList(_T("RichEdit"));
			if( pDefaultAttributes ) {
				m_pEditUI->ApplyAttributeList(pDefaultAttributes);
			}
			m_pEditUI->SetBkColor(0xFFFFFFFF);
			m_pEditUI->SetRich(false);
			m_pEditUI->SetMultiLine(false);
			m_pEditUI->SetWantReturn(true);
			m_pEditUI->SetFloat(true);
			m_pEditUI->SetAttribute(_T("autohscroll"), _T("true"));
			Add(m_pEditUI);
		}
		if (m_pComboBoxUI)
		{
			RECT rc = {0,0,0,0};
			m_pComboBoxUI->SetPos(rc);
		}

		return m_pEditUI;
	}

	BOOL CListExUI::CheckColumComboBoxable(int nColum)
	{
		CListContainerHeaderItemUI* pHItem = static_cast<CListContainerHeaderItemUI*>(m_pHeader->GetItemAt(nColum));
		return pHItem != NULL? pHItem->GetColumeComboable() : FALSE;
	}

	CComboBoxUI* CListExUI::GetComboBoxUI()
	{
		if (m_pComboBoxUI == NULL)
		{
			m_pComboBoxUI = new CComboBoxUI;
			m_pComboBoxUI->SetName(_T("ListEx_Combo"));
			LPCTSTR pDefaultAttributes = GetManager()->GetDefaultAttributeList(_T("Combo"));
			if( pDefaultAttributes ) {
				m_pComboBoxUI->ApplyAttributeList(pDefaultAttributes);
			}

			Add(m_pComboBoxUI);
		}
		if (m_pEditUI)
		{
			RECT rc = {0,0,0,0};
			m_pEditUI->SetPos(rc);
		}

		return m_pComboBoxUI;
	}

	BOOL CListExUI::CheckColumCheckBoxable(int nColum)
	{
		CControlUI* p = m_pHeader->GetItemAt(nColum);
		CListContainerHeaderItemUI* pHItem = static_cast<CListContainerHeaderItemUI*>(p->GetInterface(_T("ListContainerHeaderItem")));
		return pHItem != NULL? pHItem->GetColumeCheckable() : FALSE;
	}

	void CListExUI::Notify(TNotifyUI& msg)
	{	
		CDuiString strName = msg.pSender->GetName();

		//复选框
		if(_tcsicmp(msg.sType, _T("listheaditemchecked")) == 0)
		{
			BOOL bCheck = (BOOL)msg.lParam;
			//判断是否是本LIST发送的notify
			CListHeaderUI* pHeader = GetHeader();
			for (int i = 0; i < pHeader->GetCount(); i++)
			{
				if (pHeader->GetItemAt(i) == msg.pSender)
				{
					for (int i = 0; i < GetCount(); ++i) {
						CControlUI* p = GetItemAt(i);
						CListTextExtElementUI* pLItem = static_cast<CListTextExtElementUI*>(p->GetInterface(_T("ListTextExElement")));
						if (pLItem != NULL) {
							pLItem->SetCheck(bCheck);
						}
					}
					break;
				}
			}
		}
		else if (_tcsicmp(msg.sType, DUI_MSGTYPE_LISTITEMCHECKED) == 0)
		{
			for (int i = 0; i < GetCount(); ++i) {
				CControlUI* p = GetItemAt(i);
				CListTextExtElementUI* pLItem = static_cast<CListTextExtElementUI*>(p->GetInterface(_T("ListTextExElement")));
				if (pLItem != NULL && pLItem == msg.pSender)
				{
					OnListItemChecked(LOWORD(msg.wParam), HIWORD(msg.wParam), msg.lParam);
					break;
				}
			}
		}

		//编辑框、组合框
		if (_tcsicmp(strName, _T("ListEx_Edit")) == 0 && m_pEditUI && m_nRow >= 0 && m_nColum >= 0)
		{
			if(_tcsicmp(msg.sType, DUI_MSGTYPE_SETFOCUS) == 0)
			{

			}
			else if(_tcsicmp(msg.sType, DUI_MSGTYPE_KILLFOCUS) == 0)
			{
				CDuiString sText = m_pEditUI->GetText();
				CListTextExtElementUI* pRowCtrl = (CListTextExtElementUI*)GetItemAt(m_nRow);
				if (pRowCtrl)
				{
					pRowCtrl->SetText(m_nColum, sText);
				}

				//重置当前行列
				SetEditRowAndColum(-1, -1);

				//隐藏编辑框
				RECT rc = {0,0,0,0};
				m_pEditUI->SetPos(rc);
				m_pEditUI->SetVisible(false);
			}
		}
		else if (_tcsicmp(strName, _T("ListEx_Combo")) == 0 && m_pComboBoxUI && m_nRow >= 0 && m_nColum >= 0)
		{
			int  iCurSel, iOldSel;
			iCurSel = msg.wParam;
			iOldSel = msg.lParam;

			if(_tcsicmp(msg.sType, DUI_MSGTYPE_SETFOCUS) == 0)
			{

			}
			else if(_tcsicmp(msg.sType, DUI_MSGTYPE_KILLFOCUS) == 0)
			{
			}
			else if(_tcsicmp(msg.sType, DUI_MSGTYPE_LISTITEMSELECT) == 0 && iOldSel >= 0)
			{
				CListTextExtElementUI* pRowCtrl = (CListTextExtElementUI*)GetItemAt(m_nRow);
				if (pRowCtrl)
				{
					pRowCtrl->SetText(m_nColum, m_pComboBoxUI->GetText());
				}

				//隐藏组合框
				RECT rc = {0,0,0,0};
				m_pComboBoxUI->SetPos(rc);
			}
		}
		else if(_tcsicmp(msg.sType, _T("scroll")) == 0 && (m_pComboBoxUI || m_pEditUI) && m_nRow >= 0 && m_nColum >= 0)
		{
			HideEditAndComboCtrl();
		}
	}
	void CListExUI::HideEditAndComboCtrl()
	{
		//隐藏编辑框
		RECT rc = {0,0,0,0};
		if(m_pEditUI)
		{	
			m_pEditUI->SetPos(rc);

			m_pEditUI->SetVisible(false);
		}

		if(m_pComboBoxUI)
		{	
			m_pComboBoxUI->SetPos(rc);
		}
	}
	IListComboCallbackUI* CListExUI::GetTextArrayCallback() const
	{
		return m_pXCallback;
	}

	void CListExUI::SetTextArrayCallback(IListComboCallbackUI* pCallback)
	{
		m_pXCallback = pCallback;
	}
	void CListExUI::OnListItemClicked(int nIndex, int nColum, RECT* lpRCColum, LPCTSTR lpstrText)
	{
		RECT rc = {0,0,0,0};
		if (nColum < 0)
		{
			if (m_pEditUI)
			{
				m_pEditUI->SetPos(rc);

				m_pEditUI->SetVisible(false);
			}
			if (m_pComboBoxUI)
			{
				m_pComboBoxUI->SetPos(rc);
			}
		}
		else
		{
			if (CheckColumEditable(nColum) && GetEditUI())
			{
				//保存当前行列
				SetEditRowAndColum(nIndex, nColum);
				
				m_pEditUI->SetVisible(true);
				//移动位置
				m_pEditUI->SetFixedWidth(lpRCColum->right - lpRCColum->left);
				m_pEditUI->SetFixedHeight(lpRCColum->bottom - lpRCColum->top);
				m_pEditUI->SetFixedXY(CDuiSize(lpRCColum->left,lpRCColum->top));
				SIZE szTextSize = CRenderEngine::GetTextSize(m_pManager->GetPaintDC(), m_pManager, _T("TTT"), m_ListInfo.nFont, DT_CALCRECT | DT_SINGLELINE);
				m_pEditUI->SetTextPadding(CDuiRect(2, (lpRCColum->bottom - lpRCColum->top - szTextSize.cy) / 2, 2, 0));
				//设置文字
				m_pEditUI->SetText(lpstrText);

				m_pEditUI->SetFocus();
			}
			else if(CheckColumComboBoxable(nColum) && GetComboBoxUI())
			{
				//重置组合框
				m_pComboBoxUI->RemoveAll();

				//保存当前行列
				SetEditRowAndColum(nIndex, nColum);

				//设置文字
				m_pComboBoxUI->SetText(lpstrText);

				//获取
				if (m_pXCallback)
				{
					m_pXCallback->GetItemComboTextArray(m_pComboBoxUI, nIndex, nColum);
				}

				//移动位置
				m_pComboBoxUI->SetPos(*lpRCColum);
				m_pComboBoxUI->SetVisible(TRUE);
			}
			else
			{
				if (m_pEditUI)
				{
					m_pEditUI->SetPos(rc);

					m_pEditUI->SetVisible(false);
				}
				if (m_pComboBoxUI)
				{
					m_pComboBoxUI->SetPos(rc);
				}
			}
		}
	}
	void CListExUI::OnListItemChecked(int nIndex, int nColum, BOOL bChecked)
	{
		CControlUI* p = m_pHeader->GetItemAt(nColum);
		CListContainerHeaderItemUI* pHItem = static_cast<CListContainerHeaderItemUI*>(p->GetInterface(_T("ListContainerHeaderItem")));
		if (pHItem == NULL)
		{
			return;
		}

		//如果选中，那么检查是否全部都处于选中状态
		if (bChecked)
		{
			BOOL bCheckAll = TRUE;
			for(int i = 0; i < GetCount(); i++) 
			{
				CControlUI* p = GetItemAt(i);
				CListTextExtElementUI* pLItem = static_cast<CListTextExtElementUI*>(p->GetInterface(_T("ListTextExElement")));
				if( pLItem != NULL && !pLItem->GetCheck()) 
				{
					bCheckAll = FALSE;
					break;
				}
			}
			if (bCheckAll)
			{
				pHItem->SetCheck(TRUE);
			}
			else
			{
				pHItem->SetCheck(FALSE);
			}
		}
		else
		{
			pHItem->SetCheck(FALSE);
		}
	}
	void CListExUI::DoEvent(TEventUI& event)
	{
		if (event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_SCROLLWHEEL)
		{
			HideEditAndComboCtrl();
		}

		CListUI::DoEvent(event);
	}
	void CListExUI::SetColumItemColor(int nIndex, int nColum, DWORD iBKColor)
	{
		CControlUI* p = GetItemAt(nIndex);
		CListTextExtElementUI* pLItem = static_cast<CListTextExtElementUI*>(p->GetInterface(_T("ListTextExElement")));
		if( pLItem != NULL) 
		{
			DWORD iTextBkColor = iBKColor;
			pLItem->SetColumItemColor(nColum, iTextBkColor);
		}
	}

	BOOL CListExUI::GetColumItemColor(int nIndex, int nColum, DWORD& iBKColor)
	{
		CControlUI* p = GetItemAt(nIndex);
		CListTextExtElementUI* pLItem = static_cast<CListTextExtElementUI*>(p->GetInterface(_T("ListTextExElement")));
		if( pLItem == NULL) 
		{
			return FALSE;
		}
		pLItem->GetColumItemColor(nColum, iBKColor);
		return TRUE;
	}

	/////////////////////////////////////////////////////////////////////////////////////
	//
	//
	IMPLEMENT_DUICONTROL(CListContainerHeaderItemUI)

	CListContainerHeaderItemUI::CListContainerHeaderItemUI() : 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),
		m_bEditable(FALSE),m_bComboable(FALSE),m_bCheckBoxable(FALSE),m_uCheckBoxState(0),m_bChecked(FALSE),m_pOwner(NULL)
	{
		SetTextPadding(CDuiRect(2, 0, 2, 0));
		ptLastMouse.x = ptLastMouse.y = 0;
		SetMinWidth(16);
	}

	LPCTSTR CListContainerHeaderItemUI::GetClass() const
	{
		return _T("ListContainerHeaderItemUI");
	}

	LPVOID CListContainerHeaderItemUI::GetInterface(LPCTSTR pstrName)
	{
		if( _tcsicmp(pstrName, _T("ListContainerHeaderItem")) == 0 ) return this;
		return CContainerUI::GetInterface(pstrName);
	}

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

	void CListContainerHeaderItemUI::SetEnabled(BOOL bEnable)
	{
		CContainerUI::SetEnabled(bEnable);
		if( !IsEnabled() ) {
			m_uButtonState = 0;
		}
	}

	BOOL CListContainerHeaderItemUI::IsDragable() const
	{
		return m_bDragable;
	}

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

	DWORD CListContainerHeaderItemUI::GetSepWidth() const
	{
		if(m_pManager != NULL) m_pManager->GetDPIObj()->Scale(m_iSepWidth);
		return m_iSepWidth;
	}

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

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

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

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


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

	RECT CListContainerHeaderItemUI::GetTextPadding() const
	{
		RECT rcTextPadding = m_rcTextPadding;
		if(m_pManager != NULL) m_pManager->GetDPIObj()->Scale(&rcTextPadding);
		return rcTextPadding;
	}

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

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

	BOOL CListContainerHeaderItemUI::IsShowHtml()
	{
		return m_bShowHtml;
	}

	void CListContainerHeaderItemUI::SetShowHtml(BOOL bShowHtml)
	{
		if( m_bShowHtml == bShowHtml ) return;

		m_bShowHtml = bShowHtml;
		Invalidate();
	}

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

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

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

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

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

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

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

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

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

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

	void CListContainerHeaderItemUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
	{
		if( _tcsicmp(pstrName, _T("dragable")) == 0 ) SetDragable(_tcsicmp(pstrValue, _T("true")) == 0);
		else if( _tcsicmp(pstrName, _T("sepwidth")) == 0 ) SetSepWidth(_ttoi(pstrValue));
		else if( _tcsicmp(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( _tcsicmp(pstrName, _T("endellipsis")) == 0 ) 
		{
			if( _tcsicmp(pstrValue, _T("true")) == 0 ) m_uTextStyle |= DT_END_ELLIPSIS;
			else m_uTextStyle &= ~DT_END_ELLIPSIS;
		}    
		else if( _tcsicmp(pstrName, _T("font")) == 0 ) SetFont(_ttoi(pstrValue));
		else if( _tcsicmp(pstrName, _T("textcolor")) == 0 ) 
		{
			if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
			LPTSTR pstr = NULL;
			DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
			SetTextColor(clrColor);
		}
		else if( _tcsicmp(pstrName, _T("textpadding")) == 0 ) 
		{
			RECT rcTextPadding = { 0 };
			LPTSTR pstr = NULL;
			rcTextPadding.left = _tcstol(pstrValue, &pstr, 10);
			rcTextPadding.top = _tcstol(pstr + 1, &pstr, 10);
			rcTextPadding.right = _tcstol(pstr + 1, &pstr, 10);
			rcTextPadding.bottom = _tcstol(pstr + 1, &pstr, 10);
			SetTextPadding(rcTextPadding);
		}
		else if( _tcsicmp(pstrName, _T("showhtml")) == 0 ) SetShowHtml(_tcsicmp(pstrValue, _T("true")) == 0);
		else if( _tcsicmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("pushedimage")) == 0 ) SetPushedImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("sepimage")) == 0 ) SetSepImage(pstrValue);

		else if( _tcsicmp(pstrName, _T("editable")) == 0 ) SetColumeEditable(_tcsicmp(pstrValue, _T("true")) == 0);
		else if( _tcsicmp(pstrName, _T("comboable")) == 0 ) SetColumeComboable(_tcsicmp(pstrValue, _T("true")) == 0);
		else if( _tcsicmp(pstrName, _T("checkable")) == 0 ) SetColumeCheckable(_tcsicmp(pstrValue, _T("true")) == 0);
		else if( _tcsicmp(pstrName, _T("checkboxwidth")) == 0 ) SetCheckBoxWidth(_ttoi(pstrValue));
		else if( _tcsicmp(pstrName, _T("checkboxheight")) == 0 ) SetCheckBoxHeight(_ttoi(pstrValue));
		else if( _tcsicmp(pstrName, _T("checkboxnormalimage")) == 0 ) SetCheckBoxNormalImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxhotimage")) == 0 ) SetCheckBoxHotImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxpushedimage")) == 0 ) SetCheckBoxPushedImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxfocusedimage")) == 0 ) SetCheckBoxFocusedImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxdisabledimage")) == 0 ) SetCheckBoxDisabledImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxselectedimage")) == 0 ) SetCheckBoxSelectedImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxforeimage")) == 0 ) SetCheckBoxForeImage(pstrValue);

		else CContainerUI::SetAttribute(pstrName, pstrValue);
	}

	void CListContainerHeaderItemUI::DoEvent(TEventUI& event)
	{
		if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
			if( m_pParent != NULL ) m_pParent->DoEvent(event);
			else CContainerUI::DoEvent(event);
			return;
		}

		//CheckBoxAble
		if (m_bCheckBoxable)
		{
			RECT rcCheckBox;
			GetCheckBoxRect(rcCheckBox);

			if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
			{
				if( ::PtInRect(&rcCheckBox, event.ptMouse)) 
				{
					m_uCheckBoxState |= UISTATE_PUSHED | UISTATE_CAPTURED;
					Invalidate();
				}
			}
			else if( event.Type == UIEVENT_MOUSEMOVE )
			{
				if( (m_uCheckBoxState & UISTATE_CAPTURED) != 0 ) 
				{
					if( ::PtInRect(&rcCheckBox, event.ptMouse) ) 
						m_uCheckBoxState |= UISTATE_PUSHED;
					else 
						m_uCheckBoxState &= ~UISTATE_PUSHED;
					Invalidate();
				}
				else if (::PtInRect(&rcCheckBox, event.ptMouse))
				{
					m_uCheckBoxState |= UISTATE_HOT;
					Invalidate();
				}
				else
				{
					m_uCheckBoxState &= ~UISTATE_HOT;
					Invalidate();
				}
			}
			else if( event.Type == UIEVENT_BUTTONUP )
			{
				if( (m_uCheckBoxState & UISTATE_CAPTURED) != 0 )
				{
					if( ::PtInRect(&rcCheckBox, event.ptMouse) ) 
					{
						SetCheck(!GetCheck());
						CContainerUI* pOwner = (CContainerUI*)m_pParent;
						if (pOwner)
						{
							m_pManager->SendNotify(this, DUI_MSGTYPE_LISTHEADITEMCHECKED, pOwner->GetItemIndex(this), m_bChecked);
						}

					}
					m_uCheckBoxState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED);
					Invalidate();
				}
				else if (::PtInRect(&rcCheckBox, event.ptMouse))
				{

				}
			}
			else if( event.Type == UIEVENT_MOUSEENTER )
			{
				if( ::PtInRect(&rcCheckBox, event.ptMouse) ) 
				{
					m_uCheckBoxState |= UISTATE_HOT;
					Invalidate();
				}
			}
			else if( event.Type == UIEVENT_MOUSELEAVE )
			{
				m_uCheckBoxState &= ~UISTATE_HOT;
				Invalidate();
			}
		}

		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)
				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_LISTHEADERCLICK);
				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)
				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;
		}
		CContainerUI::DoEvent(event);
	}

	SIZE CListContainerHeaderItemUI::EstimateSize(SIZE szAvailable)
	{
		if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetDefaultFontInfo()->tm.tmHeight + 14);
		return CContainerUI::EstimateSize(szAvailable);
	}

	RECT CListContainerHeaderItemUI::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 CListContainerHeaderItemUI::PaintStatusImage(HDC hDC)
	{
		//HeadItem Bkgnd
		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) ) {}
		}
		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) ) {}
		}
		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) ) {}
		}
		else {
			if( !m_sNormalImage.IsEmpty() ) {
				if( !DrawImage(hDC, (LPCTSTR)m_sNormalImage) ) {}
			}
		}

		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) ) {}
		}

		if(m_bCheckBoxable)
		{
			m_uCheckBoxState &= ~UISTATE_PUSHED;

			if( (m_uCheckBoxState & UISTATE_SELECTED) != 0 ) {
				if( !m_sCheckBoxSelectedImage.IsEmpty() ) {
					if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxSelectedImage) ) {}
					else goto Label_ForeImage;
				}
			}

			if( IsFocused() ) m_uCheckBoxState |= UISTATE_FOCUSED;
			else m_uCheckBoxState &= ~ UISTATE_FOCUSED;
			if( !IsEnabled() ) m_uCheckBoxState |= UISTATE_DISABLED;
			else m_uCheckBoxState &= ~ UISTATE_DISABLED;

			if( (m_uCheckBoxState & UISTATE_DISABLED) != 0 ) {
				if( !m_sCheckBoxDisabledImage.IsEmpty() ) {
					if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxDisabledImage) ) {}
					else return;
				}
			}
			else if( (m_uCheckBoxState & UISTATE_PUSHED) != 0 ) {
				if( !m_sCheckBoxPushedImage.IsEmpty() ) {
					if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxPushedImage) ) {}
					else return;
				}
			}
			else if( (m_uCheckBoxState & UISTATE_HOT) != 0 ) {
				if( !m_sCheckBoxHotImage.IsEmpty() ) {
					if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxHotImage) ) {}
					else return;
				}
			}
			else if( (m_uCheckBoxState & UISTATE_FOCUSED) != 0 ) {
				if( !m_sCheckBoxFocusedImage.IsEmpty() ) {
					if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxFocusedImage) ) {}
					else return;
				}
			}

			if( !m_sCheckBoxNormalImage.IsEmpty() ) {
				if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxNormalImage) ) {}
				else return;
			}

Label_ForeImage:
			if( !m_sCheckBoxForeImage.IsEmpty() ) {
				if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxForeImage) ) {}
			}
		}
	}

	void CListContainerHeaderItemUI::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_bCheckBoxable) {
			RECT rcCheck;
			GetCheckBoxRect(rcCheck);
			rcText.left += (rcCheck.right - rcCheck.left);
		}

		CDuiString sText = GetText();
		if( sText.IsEmpty() ) return;

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

	BOOL CListContainerHeaderItemUI::GetColumeEditable()
	{
		return m_bEditable;
	}

	void CListContainerHeaderItemUI::SetColumeEditable(BOOL bEnable)
	{
		m_bEditable = bEnable;
	}

	BOOL CListContainerHeaderItemUI::GetColumeComboable()
	{
		return m_bComboable;
	}

	void CListContainerHeaderItemUI::SetColumeComboable(BOOL bEnable)
	{
		m_bComboable = bEnable;
	}

	BOOL CListContainerHeaderItemUI::GetColumeCheckable()
	{
		return m_bCheckBoxable;
	}
	void CListContainerHeaderItemUI::SetColumeCheckable(BOOL bEnable)
	{
		m_bCheckBoxable = bEnable;
	}
	void CListContainerHeaderItemUI::SetCheck(BOOL bCheck)
	{
		if( m_bChecked == bCheck ) return;
		m_bChecked = bCheck;
		if( m_bChecked ) m_uCheckBoxState |= UISTATE_SELECTED;
		else m_uCheckBoxState &= ~UISTATE_SELECTED;
		Invalidate();
	}

	BOOL CListContainerHeaderItemUI::GetCheck()
	{
		return m_bChecked;
	}
	BOOL CListContainerHeaderItemUI::DrawCheckBoxImage(HDC hDC, LPCTSTR pStrImage, LPCTSTR pStrModify)
	{
		RECT rcCheckBox;
		GetCheckBoxRect(rcCheckBox);
		return CRenderEngine::DrawImageString(hDC, m_pManager, rcCheckBox, m_rcPaint, pStrImage, pStrModify);
	}
	LPCTSTR CListContainerHeaderItemUI::GetCheckBoxNormalImage()
	{
		return m_sCheckBoxNormalImage;
	}

	void CListContainerHeaderItemUI::SetCheckBoxNormalImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxNormalImage = pStrImage;
	}

	LPCTSTR CListContainerHeaderItemUI::GetCheckBoxHotImage()
	{
		return m_sCheckBoxHotImage;
	}

	void CListContainerHeaderItemUI::SetCheckBoxHotImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxHotImage = pStrImage;
	}

	LPCTSTR CListContainerHeaderItemUI::GetCheckBoxPushedImage()
	{
		return m_sCheckBoxPushedImage;
	}

	void CListContainerHeaderItemUI::SetCheckBoxPushedImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxPushedImage = pStrImage;
	}

	LPCTSTR CListContainerHeaderItemUI::GetCheckBoxFocusedImage()
	{
		return m_sCheckBoxFocusedImage;
	}

	void CListContainerHeaderItemUI::SetCheckBoxFocusedImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxFocusedImage = pStrImage;
	}

	LPCTSTR CListContainerHeaderItemUI::GetCheckBoxDisabledImage()
	{
		return m_sCheckBoxDisabledImage;
	}

	void CListContainerHeaderItemUI::SetCheckBoxDisabledImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxDisabledImage = pStrImage;
	}
	LPCTSTR CListContainerHeaderItemUI::GetCheckBoxSelectedImage()
	{
		return m_sCheckBoxSelectedImage;
	}

	void CListContainerHeaderItemUI::SetCheckBoxSelectedImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxSelectedImage = pStrImage;
	}
	LPCTSTR CListContainerHeaderItemUI::GetCheckBoxForeImage()
	{
		return m_sCheckBoxForeImage;
	}

	void CListContainerHeaderItemUI::SetCheckBoxForeImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxForeImage = pStrImage;
	}
	int CListContainerHeaderItemUI::GetCheckBoxWidth() const
	{
		if(m_pManager) m_pManager->GetDPIObj()->Scale(m_cxyCheckBox.cx);
		return m_cxyCheckBox.cx;
	}

	void CListContainerHeaderItemUI::SetCheckBoxWidth(int cx)
	{
		if( cx < 0 ) return; 
		m_cxyCheckBox.cx = cx;
	}

	int CListContainerHeaderItemUI::GetCheckBoxHeight()  const 
	{
		if(m_pManager) m_pManager->GetDPIObj()->Scale(m_cxyCheckBox.cy);
		return m_cxyCheckBox.cy;
	}

	void CListContainerHeaderItemUI::SetCheckBoxHeight(int cy)
	{
		if( cy < 0 ) return; 
		m_cxyCheckBox.cy = cy;
	}
	void CListContainerHeaderItemUI::GetCheckBoxRect(RECT &rc)
	{
		memset(&rc, 0x00, sizeof(rc)); 
		int nItemHeight = m_rcItem.bottom - m_rcItem.top;
		rc.left = m_rcItem.left + 6;
		rc.top = m_rcItem.top + (nItemHeight - GetCheckBoxHeight()) / 2;
		rc.right = rc.left + GetCheckBoxWidth();
		rc.bottom = rc.top + GetCheckBoxHeight();
	}

	void CListContainerHeaderItemUI::SetOwner(CContainerUI* pOwner)
	{
		m_pOwner = pOwner;
	}
	CContainerUI* CListContainerHeaderItemUI::GetOwner()
	{
		return m_pOwner;
	}
	/////////////////////////////////////////////////////////////////////////////////////
	//
	//
	IMPLEMENT_DUICONTROL(CListTextExtElementUI)

	CListTextExtElementUI::CListTextExtElementUI() : 
	m_nLinks(0), m_nHoverLink(-1), m_pOwner(NULL),m_uCheckBoxState(0),m_bChecked(FALSE)
	{
		::ZeroMemory(&m_rcLinks, sizeof(m_rcLinks));
		m_cxyCheckBox.cx = m_cxyCheckBox.cy = 0;

		::ZeroMemory(&ColumCorlorArray, sizeof(ColumCorlorArray));
	}

	CListTextExtElementUI::~CListTextExtElementUI()
	{
		CDuiString* pText;
		for( int it = 0; it < m_aTexts.GetSize(); it++ ) {
			pText = static_cast<CDuiString*>(m_aTexts[it]);
			if( pText ) delete pText;
		}
		m_aTexts.Empty();
	}

	LPCTSTR CListTextExtElementUI::GetClass() const
	{
		return _T("ListTextExElementUI");
	}

	LPVOID CListTextExtElementUI::GetInterface(LPCTSTR pstrName)
	{
		if( _tcsicmp(pstrName, _T("ListTextExElement")) == 0 ) return static_cast<CListTextExtElementUI*>(this);
		return CListLabelElementUI::GetInterface(pstrName);
	}

	UINT CListTextExtElementUI::GetControlFlags() const
	{
		return UIFLAG_WANTRETURN | ( (IsEnabled() && m_nLinks > 0) ? UIFLAG_SETCURSOR : 0);
	}

	LPCTSTR CListTextExtElementUI::GetText(int iIndex) const
	{
		CDuiString* pText = static_cast<CDuiString*>(m_aTexts.GetAt(iIndex));
		if( pText ) return pText->GetData();
		return NULL;
	}

	void CListTextExtElementUI::SetText(int iIndex, LPCTSTR pstrText)
	{
		if( m_pOwner == NULL ) return;
		TListInfoUI* pInfo = m_pOwner->GetListInfo();
		if( iIndex < 0 || iIndex >= pInfo->nColumns ) return;
		while( m_aTexts.GetSize() < pInfo->nColumns ) { m_aTexts.Add(NULL); }

		CDuiString* pText = static_cast<CDuiString*>(m_aTexts[iIndex]);
		if( (pText == NULL && pstrText == NULL) || (pText && *pText == pstrText) ) return;

		if ( pText )
			pText->Assign(pstrText);
		else
			m_aTexts.SetAt(iIndex, new CDuiString(pstrText));
		Invalidate();
	}

	void CListTextExtElementUI::SetOwner(CControlUI* pOwner)
	{
		CListElementUI::SetOwner(pOwner);
		m_pOwner = static_cast<CListUI*>(pOwner->GetInterface(_T("List")));
	}

	CDuiString* CListTextExtElementUI::GetLinkContent(int iIndex)
	{
		if( iIndex >= 0 && iIndex < m_nLinks ) return &m_sLinks[iIndex];
		return NULL;
	}

	void CListTextExtElementUI::DoEvent(TEventUI& event)
	{
		if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
			if( m_pOwner != NULL ) m_pOwner->DoEvent(event);
			else CListLabelElementUI::DoEvent(event);
			return;
		}

		// When you hover over a link
		if( event.Type == UIEVENT_SETCURSOR ) {
			for( int i = 0; i < m_nLinks; i++ ) {
				if( ::PtInRect(&m_rcLinks[i], event.ptMouse) ) {
					::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)));
					return;
				}
			}      
		}
		if( event.Type == UIEVENT_BUTTONUP && IsEnabled() ) {
			for( int i = 0; i < m_nLinks; i++ ) {
				if( ::PtInRect(&m_rcLinks[i], event.ptMouse) ) {
					m_pManager->SendNotify(this, DUI_MSGTYPE_LINK, i);
					return;
				}
			}
		}
		if( m_nLinks > 0 && event.Type == UIEVENT_MOUSEMOVE ) {
			int nHoverLink = -1;
			for( int i = 0; i < m_nLinks; i++ ) {
				if( ::PtInRect(&m_rcLinks[i], event.ptMouse) ) {
					nHoverLink = i;
					break;
				}
			}

			if(m_nHoverLink != nHoverLink) {
				Invalidate();
				m_nHoverLink = nHoverLink;
			}
		}
		if( m_nLinks > 0 && event.Type == UIEVENT_MOUSELEAVE ) {
			if(m_nHoverLink != -1) {
				Invalidate();
				m_nHoverLink = -1;
			}
		}

		//检查是否需要显示编辑框或者组合框	
		CListExUI * pListCtrl = (CListExUI *)m_pOwner;
		int nColum = HitTestColum(event.ptMouse);
		if(event.Type == UIEVENT_BUTTONUP && m_pOwner->IsFocused())
		{
			RECT rc = {0,0,0,0};
			if (nColum >= 0)
			{
				GetColumRect(nColum, rc);
			}

			pListCtrl->OnListItemClicked(GetIndex(), nColum, &rc, GetText(nColum));
		}

		//检查是否需要显示CheckBox
		TListInfoUI* pInfo = m_pOwner->GetListInfo();
		for( int i = 0; i < pInfo->nColumns; i++ )
		{
			if (pListCtrl->CheckColumCheckBoxable(i))
			{
				RECT rcCheckBox;
				GetCheckBoxRect(i, rcCheckBox);

				if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
				{
					if( ::PtInRect(&rcCheckBox, event.ptMouse)) 
					{
						m_uCheckBoxState |= UISTATE_PUSHED | UISTATE_CAPTURED;
						Invalidate();
					}
				}
				else if( event.Type == UIEVENT_MOUSEMOVE )
				{
					if( (m_uCheckBoxState & UISTATE_CAPTURED) != 0 ) 
					{
						if( ::PtInRect(&rcCheckBox, event.ptMouse) ) 
							m_uCheckBoxState |= UISTATE_PUSHED;
						else 
							m_uCheckBoxState &= ~UISTATE_PUSHED;
						Invalidate();
					}
				}
				else if( event.Type == UIEVENT_BUTTONUP )
				{
					if( (m_uCheckBoxState & UISTATE_CAPTURED) != 0 )
					{
						if( ::PtInRect(&rcCheckBox, event.ptMouse) ) 
						{
							SetCheck(!GetCheck());
							if (m_pManager)
							{
								m_pManager->SendNotify(this, DUI_MSGTYPE_LISTITEMCHECKED, MAKEWPARAM(GetIndex(), 0), m_bChecked);
							}
						}
						m_uCheckBoxState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED);
						Invalidate();
					}
				}
				else if( event.Type == UIEVENT_MOUSEENTER )
				{
					if( ::PtInRect(&rcCheckBox, event.ptMouse) ) 
					{
						m_uCheckBoxState |= UISTATE_HOT;
						Invalidate();
					}
				}
				else if( event.Type == UIEVENT_MOUSELEAVE )
				{
					m_uCheckBoxState &= ~UISTATE_HOT;
					Invalidate();
				}
			}
		}

		CListLabelElementUI::DoEvent(event);
	}

	SIZE CListTextExtElementUI::EstimateSize(SIZE szAvailable)
	{
		TListInfoUI* pInfo = NULL;
		if( m_pOwner ) pInfo = m_pOwner->GetListInfo();

		SIZE cXY = m_cxyFixed;
		if( cXY.cy == 0 && m_pManager != NULL && pInfo != NULL) {
			cXY.cy = m_pManager->GetFontInfo(pInfo->nFont)->tm.tmHeight + 8;
			cXY.cy += pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom;
		}

		return cXY;
	}

	void CListTextExtElementUI::DrawItemText(HDC hDC, const RECT& rcItem)
	{
		if( m_pOwner == NULL ) return;
		TListInfoUI* pInfo = m_pOwner->GetListInfo();
		DWORD iTextColor = pInfo->dwTextColor;

		if( (m_uButtonState & UISTATE_HOT) != 0 ) {
			iTextColor = pInfo->dwHotTextColor;
		}
		if( IsSelected() ) {
			iTextColor = pInfo->dwSelectedTextColor;
		}
		if( !IsEnabled() ) {
			iTextColor = pInfo->dwDisabledTextColor;
		}
		IListCallbackUI* pCallback = m_pOwner->GetTextCallback();
		//DUIASSERT(pCallback);
		//if( pCallback == NULL ) return;

		CListExUI * pListCtrl = (CListExUI *)m_pOwner;
		m_nLinks = 0;
		int nLinks = lengthof(m_rcLinks);
		for( int i = 0; i < pInfo->nColumns; i++ )
		{
			RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.bottom };

			DWORD iTextBkColor = 0;
			if (GetColumItemColor(i, iTextBkColor))
			{	
				CRenderEngine::DrawColor(hDC, rcItem, iTextBkColor);
			}

			rcItem.left += pInfo->rcTextPadding.left;
			rcItem.right -= pInfo->rcTextPadding.right;
			rcItem.top += pInfo->rcTextPadding.top;
			rcItem.bottom -= pInfo->rcTextPadding.bottom;

			//检查是否需要显示CheckBox
			if (pListCtrl->CheckColumCheckBoxable(i))
			{
				RECT rcCheckBox;
				GetCheckBoxRect(i, rcCheckBox);
				rcItem.left += (rcCheckBox.right - rcCheckBox.left);
			}

			CDuiString strText;//不使用LPCTSTR，否则限制太多 by cddjr 2011/10/20
			if( pCallback ) strText = pCallback->GetItemText(this, m_iIndex, i);
			else strText.Assign(GetText(i));
			if( pInfo->bShowHtml )
				CRenderEngine::DrawHtmlText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \
				&m_rcLinks[m_nLinks], &m_sLinks[m_nLinks], nLinks, pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);
			else
				CRenderEngine::DrawText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \
				pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);

			m_nLinks += nLinks;
			nLinks = lengthof(m_rcLinks) - m_nLinks; 
		}
		for( int i = m_nLinks; i < lengthof(m_rcLinks); i++ ) {
			::ZeroMemory(m_rcLinks + i, sizeof(RECT));
			((CDuiString*)(m_sLinks + i))->Empty();
		}
	}
	void CListTextExtElementUI::PaintStatusImage(HDC hDC)
	{
		CListExUI * pListCtrl = (CListExUI *)m_pOwner;
		TListInfoUI* pInfo = m_pOwner->GetListInfo();
		for( int i = 0; i < pInfo->nColumns; i++ )
		{
			if (pListCtrl->CheckColumCheckBoxable(i))
			{
				RECT rcCheckBox;
				GetCheckBoxRect(i, rcCheckBox);

				m_uCheckBoxState &= ~UISTATE_PUSHED;

				if( (m_uCheckBoxState & UISTATE_SELECTED) != 0 ) {
					if( !m_sCheckBoxSelectedImage.IsEmpty() ) {
						if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxSelectedImage, NULL, rcCheckBox) ) {}
						else goto Label_ForeImage;
					}
				}

				if( IsFocused() ) m_uCheckBoxState |= UISTATE_FOCUSED;
				else m_uCheckBoxState &= ~ UISTATE_FOCUSED;
				if( !IsEnabled() ) m_uCheckBoxState |= UISTATE_DISABLED;
				else m_uCheckBoxState &= ~ UISTATE_DISABLED;

				if( (m_uCheckBoxState & UISTATE_DISABLED) != 0 ) {
					if( !m_sCheckBoxDisabledImage.IsEmpty() ) {
						if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxDisabledImage, NULL, rcCheckBox) ) {}
						else return;
					}
				}
				else if( (m_uCheckBoxState & UISTATE_PUSHED) != 0 ) {
					if( !m_sCheckBoxPushedImage.IsEmpty() ) {
						if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxPushedImage, NULL, rcCheckBox) ) {}
						else return;
					}
				}
				else if( (m_uCheckBoxState & UISTATE_HOT) != 0 ) {
					if( !m_sCheckBoxHotImage.IsEmpty() ) {
						if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxHotImage, NULL, rcCheckBox) ) {}
						else return;
					}
				}
				else if( (m_uCheckBoxState & UISTATE_FOCUSED) != 0 ) {
					if( !m_sCheckBoxFocusedImage.IsEmpty() ) {
						if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxFocusedImage, NULL, rcCheckBox) ) {}
						else return;
					}
				}

				if( !m_sCheckBoxNormalImage.IsEmpty() ) {
					if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxNormalImage, NULL, rcCheckBox) ) {}
					else return;
				}

Label_ForeImage:
				if( !m_sCheckBoxForeImage.IsEmpty() ) {
					if( !DrawCheckBoxImage(hDC, (LPCTSTR)m_sCheckBoxForeImage, NULL, rcCheckBox) ) {}
				}
			}
		}
	}
	BOOL CListTextExtElementUI::DrawCheckBoxImage(HDC hDC, LPCTSTR pStrImage, LPCTSTR pStrModify, RECT& rcCheckBox)
	{
		return CRenderEngine::DrawImageString(hDC, m_pManager, rcCheckBox, m_rcPaint, pStrImage, pStrModify);
	}
	void CListTextExtElementUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
	{
		if( _tcsicmp(pstrName, _T("checkboxwidth")) == 0 ) SetCheckBoxWidth(_ttoi(pstrValue));
		else if( _tcsicmp(pstrName, _T("checkboxheight")) == 0 ) SetCheckBoxHeight(_ttoi(pstrValue));
		else if( _tcsicmp(pstrName, _T("checkboxnormalimage")) == 0 ) SetCheckBoxNormalImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxhotimage")) == 0 ) SetCheckBoxHotImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxpushedimage")) == 0 ) SetCheckBoxPushedImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxfocusedimage")) == 0 ) SetCheckBoxFocusedImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxdisabledimage")) == 0 ) SetCheckBoxDisabledImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxselectedimage")) == 0 ) SetCheckBoxSelectedImage(pstrValue);
		else if( _tcsicmp(pstrName, _T("checkboxforeimage")) == 0 ) SetCheckBoxForeImage(pstrValue);
		else CListLabelElementUI::SetAttribute(pstrName, pstrValue);
	}
	LPCTSTR CListTextExtElementUI::GetCheckBoxNormalImage()
	{
		return m_sCheckBoxNormalImage;
	}

	void CListTextExtElementUI::SetCheckBoxNormalImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxNormalImage = pStrImage;
	}

	LPCTSTR CListTextExtElementUI::GetCheckBoxHotImage()
	{
		return m_sCheckBoxHotImage;
	}

	void CListTextExtElementUI::SetCheckBoxHotImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxHotImage = pStrImage;
	}

	LPCTSTR CListTextExtElementUI::GetCheckBoxPushedImage()
	{
		return m_sCheckBoxPushedImage;
	}

	void CListTextExtElementUI::SetCheckBoxPushedImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxPushedImage = pStrImage;
	}

	LPCTSTR CListTextExtElementUI::GetCheckBoxFocusedImage()
	{
		return m_sCheckBoxFocusedImage;
	}

	void CListTextExtElementUI::SetCheckBoxFocusedImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxFocusedImage = pStrImage;
	}

	LPCTSTR CListTextExtElementUI::GetCheckBoxDisabledImage()
	{
		return m_sCheckBoxDisabledImage;
	}

	void CListTextExtElementUI::SetCheckBoxDisabledImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxDisabledImage = pStrImage;
	}
	LPCTSTR CListTextExtElementUI::GetCheckBoxSelectedImage()
	{
		return m_sCheckBoxSelectedImage;
	}

	void CListTextExtElementUI::SetCheckBoxSelectedImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxSelectedImage = pStrImage;
	}
	LPCTSTR CListTextExtElementUI::GetCheckBoxForeImage()
	{
		return m_sCheckBoxForeImage;
	}

	void CListTextExtElementUI::SetCheckBoxForeImage(LPCTSTR pStrImage)
	{
		m_sCheckBoxForeImage = pStrImage;
	}

	bool CListTextExtElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
	{
		if( !::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem) ) return true;
		DrawItemBk(hDC, m_rcItem);
		PaintStatusImage(hDC);
		DrawItemText(hDC, m_rcItem);
		return true;
	}
	void CListTextExtElementUI::GetCheckBoxRect(int nIndex, RECT &rc)
	{
		memset(&rc, 0x00, sizeof(rc));
		int nItemHeight = m_rcItem.bottom - m_rcItem.top;
		rc.left = m_rcItem.left + 6;
		rc.top = m_rcItem.top + (nItemHeight - GetCheckBoxHeight()) / 2;
		rc.right = rc.left + GetCheckBoxWidth();
		rc.bottom = rc.top + GetCheckBoxHeight();
	}
	int CListTextExtElementUI::GetCheckBoxWidth() const
	{
		return m_cxyCheckBox.cx;
	}

	void CListTextExtElementUI::SetCheckBoxWidth(int cx)
	{
		if( cx < 0 ) return; 
		m_cxyCheckBox.cx = cx;
	}

	int CListTextExtElementUI::GetCheckBoxHeight()  const 
	{
		return m_cxyCheckBox.cy;
	}

	void CListTextExtElementUI::SetCheckBoxHeight(int cy)
	{
		if( cy < 0 ) return; 
		m_cxyCheckBox.cy = cy;
	}

	void CListTextExtElementUI::SetCheck(BOOL bCheck)
	{
		if( m_bChecked == bCheck ) return;
		m_bChecked = bCheck;
		if( m_bChecked ) m_uCheckBoxState |= UISTATE_SELECTED;
		else m_uCheckBoxState &= ~UISTATE_SELECTED;
		Invalidate();
	}

	BOOL  CListTextExtElementUI::GetCheck() const
	{
		return m_bChecked;
	}

	int CListTextExtElementUI::HitTestColum(POINT ptMouse)
	{
		TListInfoUI* pInfo = m_pOwner->GetListInfo();
		for( int i = 0; i < pInfo->nColumns; i++ )
		{
			RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.bottom };
			rcItem.left += pInfo->rcTextPadding.left;
			rcItem.right -= pInfo->rcTextPadding.right;
			rcItem.top += pInfo->rcTextPadding.top;
			rcItem.bottom -= pInfo->rcTextPadding.bottom;

			if( ::PtInRect(&rcItem, ptMouse)) 
			{
				return i;
			}
		}
		return -1;
	}

	BOOL CListTextExtElementUI::CheckColumEditable(int nColum)
	{
		return m_pOwner->CheckColumEditable(nColum);
	}
	void CListTextExtElementUI::GetColumRect(int nColum, RECT &rc)
	{
		TListInfoUI* pInfo = m_pOwner->GetListInfo();
		RECT rcOwnerPos = m_pOwner->GetPos();

		rc.left = pInfo->rcColumn[nColum].left + 1;
		rc.top  = 1;
		rc.right = pInfo->rcColumn[nColum].right - 1;
		rc.bottom = m_rcItem.bottom - m_rcItem.top - 1;
		OffsetRect(&rc, -rcOwnerPos.left, m_rcItem.top - rcOwnerPos.top);
	}

	void CListTextExtElementUI::SetColumItemColor(int nColum, DWORD iBKColor)
	{
		ColumCorlorArray[nColum].bEnable = TRUE;
		ColumCorlorArray[nColum].iBKColor = iBKColor;
		Invalidate();
	}
	BOOL CListTextExtElementUI::GetColumItemColor(int nColum, DWORD& iBKColor)
	{
		if (!ColumCorlorArray[nColum].bEnable)
		{
			return FALSE;
		}
		iBKColor = ColumCorlorArray[nColum].iBKColor;
		return TRUE;
	}

} // namespace DuiLib

