您的位置:首页 > 产品设计 > UI/UE

自己写的duilib树控件,如发现BUG和可优化地方请在下面回复

2012-10-22 14:11 183 查看
.h文件源代码

#ifndef __TREE_LAYOUT_H__

#define __TREE_LAYOUT_H__

namespace DuiLib{

#define kTreeDataInterface _T("TreeData")

#define kTreeLayoutInterface _T("TreeLayout")

#define kTreeChildElementInterface _T("TreeChildElement")

#define kTreeElementInterface _T("TreeElement")

class CTreeLayoutUI;

class CTreeElementUI;

typedef int ( *TREESORTPROC)(CTreeElementUI * pFirst, CTreeElementUI * pSecond, CTreeLayoutUI * pTree);

//数据节点

class UILIB_API CTreeDataUI :public CHorizontalLayoutUI

{

public:

CTreeDataUI();

public:

LPCTSTR GetClass() const;

LPVOID GetInterface(LPCTSTR pstrName);

};

//树子节点

class UILIB_API CTreeChildElementUI : public CVerticalLayoutUI

{

public:

CTreeChildElementUI();

public:

LPCTSTR GetClass() const;

LPVOID GetInterface(LPCTSTR pstrName);

virtual bool GetVisible();

};

//树节点

class UILIB_API CTreeElementUI : public CVerticalLayoutUI

{

public:

CTreeElementUI();

public:

LPCTSTR GetClass() const;

LPVOID GetInterface(LPCTSTR pstrName);

public:

CTreeDataUI * GetDataElement();

};

//树

class UILIB_API CTreeLayoutUI : public CVerticalLayoutUI

{

public:

CTreeLayoutUI(void);

public:

LPCTSTR GetClass() const;

LPVOID GetInterface(LPCTSTR pstrName);

UINT GetControlFlags() const;

void DoEvent(TEventUI& event);

void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);

public:

LPCTSTR GetItemHotImage();

void SetItemHotImage(LPCTSTR pStrImage);

LPCTSTR GetItemSelectedImage();

void SetItemSelectedImage(LPCTSTR pStrImage);

void SetItemHotColor(DWORD dwColor);

DWORD GetItemHotColor() const;

void SetItemSelectedColor(DWORD dwColor);

DWORD GetItemSelectedColor() const;

void DrawItemBk(HDC hDC);

void DoPaint(HDC hDC, const RECT& rcPaint);

public:

bool Add(CTreeElementUI* pParent, CTreeElementUI * pControl, bool bInsertLast = true);

bool Remove(CTreeElementUI* pControl, bool bDelete);

void RemoveAll();

CTreeElementUI * GetRootItem();

CTreeElementUI * GetNextItem(CTreeElementUI * pElement);

CTreeElementUI * GetChildItem(CTreeElementUI * pElement);

void Expand(CTreeElementUI * pElement, UINT nCode);

bool IsExpand(CTreeElementUI * pElement);

bool ItemHasChildren(CTreeElementUI * pElement);

void SelectItem(CTreeElementUI * pElement, UINT nCode);

CTreeElementUI * GetSelectedItem();

CTreeElementUI * GetParentItem(CTreeElementUI * pElement);

CTreeElementUI * HitTest(POINT pt);

RECT GetItemRect(CTreeElementUI * pElement);

void SortChildren(CContainerUI * pElement, TREESORTPROC pSortProc);

void SetIndent(int nIndentation);

int GetIndent();

protected:

//收缩节点

void CollapseElement(CTreeElementUI * pElement);

//展开节点

void ExpandElement(CTreeElementUI * pElement);

void QuickSort(CContainerUI * pElement, TREESORTPROC pSortProc, int nFirst, int nEnd);

protected:

CTreeElementUI *m_pSelectedItem;

CTreeElementUI *m_pUpHotItem;

DWORD m_dwItemHotColor;

DWORD m_dwItemSelectedColor;

CStdString
m_sItemHotImage;

CStdString
m_sItemSelectedImage;

int m_nIndentation;//缩进值

};

}

#endif

.cpp文件源代码

#include "StdAfx.h"

#include "UITree.h"

namespace DuiLib{

//////////////////////////数据节点//////////////////////////////////////////////////

CTreeDataUI::CTreeDataUI()

{

}

LPCTSTR CTreeDataUI::GetClass() const

{

return _T("TreeDataUI");

}

LPVOID CTreeDataUI::GetInterface(LPCTSTR pstrName)

{

if( _tcscmp(pstrName, kTreeDataInterface) == 0 ) return static_cast<CTreeDataUI*>(this);

return CContainerUI::GetInterface(pstrName);

}

//////////////////////////树子节点//////////////////////////////////////////////////

CTreeChildElementUI::CTreeChildElementUI()

{

}

LPCTSTR CTreeChildElementUI::GetClass() const

{

return _T("TreeChildElementUI");

}

LPVOID CTreeChildElementUI::GetInterface(LPCTSTR pstrName)

{

if( _tcscmp(pstrName, kTreeChildElementInterface) == 0 ) return static_cast<CTreeChildElementUI*>(this);

return CContainerUI::GetInterface(pstrName);

}

bool CTreeChildElementUI::GetVisible()

{

return m_bVisible;

}

//////////////////////////树节点////////////////////////////////////////////////////

CTreeElementUI::CTreeElementUI()

{

}

LPCTSTR CTreeElementUI::GetClass() const

{

return _T("TreeElementUI");

}

LPVOID CTreeElementUI::GetInterface(LPCTSTR pstrName)

{

if( _tcscmp(pstrName, kTreeElementInterface) == 0 ) return static_cast<CTreeElementUI*>(this);

return CContainerUI::GetInterface(pstrName);

}

CTreeDataUI * CTreeElementUI::GetDataElement()

{

CTreeDataUI * pTreeData = NULL;

for (int i = 0; i < GetCount(); i++)

{

pTreeData = static_cast<CTreeDataUI *>(GetItemAt(i)->GetInterface(kTreeDataInterface));

if (pTreeData) break;

}

return pTreeData;

}

////////////////////////////树///////////////////////////////////////////////////////

CTreeLayoutUI::CTreeLayoutUI(void)

{

m_dwItemHotColor = 0xFFE9F5FF;

m_dwItemSelectedColor = 0xFFC1E3FF;

m_pSelectedItem = NULL;

m_pUpHotItem = NULL;

m_nIndentation = 10;

}

LPCTSTR CTreeLayoutUI::GetClass() const

{

return _T("TreeLayoutUI");

}

LPVOID CTreeLayoutUI::GetInterface(LPCTSTR pstrName)

{

if( _tcscmp(pstrName, kTreeLayoutInterface) == 0 ) return static_cast<CTreeLayoutUI*>(this);

return CContainerUI::GetInterface(pstrName);

}

UINT CTreeLayoutUI::GetControlFlags() const

{

if( IsEnabled() && m_iSepHeight != 0 ) return UIFLAG_SETCURSOR;

else return 0;

}

void CTreeLayoutUI::DoEvent(TEventUI& event)

{

if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {

if( m_pParent != NULL ) m_pParent->DoEvent(event);

else CControlUI::DoEvent(event);

return;

}

if( event.Type == UIEVENT_SETFOCUS )

{

m_bFocused = true;

return;

}

if( event.Type == UIEVENT_KILLFOCUS )

{

m_bFocused = false;

return;

}

if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() && m_pVerticalScrollBar->IsEnabled() )

{

if( event.Type == UIEVENT_KEYDOWN )

{

switch( event.chKey ) {

case VK_DOWN:

LineDown();

return;

case VK_UP:

LineUp();

return;

case VK_NEXT:

PageDown();

return;

case VK_PRIOR:

PageUp();

return;

case VK_HOME:

HomeUp();

return;

case VK_END:

EndDown();

return;

}

}

else if( event.Type == UIEVENT_SCROLLWHEEL )

{

switch( LOWORD(event.wParam) ) {

case SB_LINEUP:

LineUp();

return;

case SB_LINEDOWN:

LineDown();

return;

}

}

}

else if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() && m_pHorizontalScrollBar->IsEnabled() ) {

if( event.Type == UIEVENT_KEYDOWN )

{

switch( event.chKey ) {

case VK_DOWN:

LineRight();

return;

case VK_UP:

LineLeft();

return;

case VK_NEXT:

PageRight();

return;

case VK_PRIOR:

PageLeft();

return;

case VK_HOME:

HomeLeft();

return;

case VK_END:

EndRight();

return;

}

}

else if( event.Type == UIEVENT_SCROLLWHEEL )

{

switch( LOWORD(event.wParam) ) {

case SB_LINEUP:

LineLeft();

return;

case SB_LINEDOWN:

LineRight();

return;

}

}

}

//鼠标事件

if( event.Type == UIEVENT_DBLCLICK )

{

if( IsEnabled() ) {

POINT pt = {0};

::GetCursorPos(&pt);

::ScreenToClient(GetManager()->GetPaintWindow(), &pt);

CTreeElementUI * pElement = static_cast<CTreeElementUI *>(HitTest(pt));

m_pSelectedItem = NULL;

if (pElement){

if (NULL == GetChildItem(pElement)){

m_pSelectedItem = pElement;

}

m_pManager->SendNotify(this, _T("treedbclick"), 0, MAKELPARAM(pt.x, pt.y));

}

Invalidate();

}

return;

}

if( event.Type == UIEVENT_KEYDOWN && IsEnabled() )

{

if( event.chKey == VK_RETURN ) {

Activate();

Invalidate();

return;

}

}

if( event.Type == UIEVENT_BUTTONDOWN )

{

if( IsEnabled() ){

POINT pt = {0};

::GetCursorPos(&pt);

::ScreenToClient(GetManager()->GetPaintWindow(), &pt);

CTreeElementUI * pElement = static_cast<CTreeElementUI *>(HitTest(pt));

m_pSelectedItem = NULL;

if (pElement){

if (NULL == GetChildItem(pElement)){

m_pSelectedItem = pElement;

}

m_pManager->SendNotify(this, _T("treeclick"), 0, MAKELPARAM(pt.x, pt.y));

}

Invalidate();

}

return;

}

if( event.Type == UIEVENT_RBUTTONUP )

{

if( IsEnabled() ){

POINT pt = {0};

::GetCursorPos(&pt);

::ScreenToClient(GetManager()->GetPaintWindow(), &pt);

CTreeElementUI * pElement = static_cast<CTreeElementUI *>(HitTest(pt));

m_pSelectedItem = NULL;

if (pElement){

if (NULL == GetChildItem(pElement)){

m_pSelectedItem = pElement;

}

m_pManager->SendNotify(this, _T("treerclick"), 0, MAKELPARAM(pt.x, pt.y));

}

Invalidate();

}

return;

}

if( event.Type == UIEVENT_MOUSEENTER )

{

if( IsEnabled() ) {

m_uButtonState |= UISTATE_HOT;

POINT pt = {0};

::GetCursorPos(&pt);

::ScreenToClient(GetManager()->GetPaintWindow(), &pt);

CTreeElementUI * pElement = static_cast<CTreeElementUI *>(HitTest(pt));

if (m_pUpHotItem != pElement){

if (pElement){

m_pManager->SendNotify(this, _T("treeitemhot"), 0, MAKELPARAM(pt.x, pt.y));

m_pUpHotItem = pElement;

}

}

Invalidate();

}

return;

}

if( event.Type == UIEVENT_MOUSELEAVE )

{

if( (m_uButtonState & UISTATE_HOT) != 0 ) {

m_uButtonState &= ~UISTATE_HOT;

POINT pt = {0};

::GetCursorPos(&pt);

::ScreenToClient(GetManager()->GetPaintWindow(), &pt);

CTreeElementUI * pElement = static_cast<CTreeElementUI *>(HitTest(pt));

if (m_pUpHotItem != pElement){

m_pManager->SendNotify(this, _T("treeitemleave"), 0, MAKELPARAM(pt.x, pt.y));

m_pUpHotItem = NULL;

}

Invalidate();

}

return;

}

CControlUI::DoEvent(event);

}

void CTreeLayoutUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)

{

if( _tcscmp(pstrName, _T("itemhotimage")) == 0 ) SetItemHotImage(pstrValue);

if( _tcscmp(pstrName, _T("itemselectedimage")) == 0 ) SetItemSelectedImage(pstrValue);

else if( _tcscmp(pstrName, _T("itemhotcolor")) == 0 ) {

if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);

LPTSTR pstr = NULL;

DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);

SetItemHotColor(clrColor);

}

else if( _tcscmp(pstrName, _T("itemselectedcolor")) == 0 ) {

if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);

LPTSTR pstr = NULL;

DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);

SetItemSelectedColor(clrColor);

}

else __super::SetAttribute(pstrName, pstrValue);

}

LPCTSTR CTreeLayoutUI::GetItemHotImage()

{

return m_sItemHotImage;

}

void CTreeLayoutUI::SetItemHotImage(LPCTSTR pStrImage)

{

m_sItemHotImage = pStrImage;

Invalidate();

}

LPCTSTR CTreeLayoutUI::GetItemSelectedImage()

{

return m_sItemSelectedImage;

}

void CTreeLayoutUI::SetItemSelectedImage(LPCTSTR pStrImage)

{

m_sItemSelectedImage = pStrImage;

Invalidate();

}

void CTreeLayoutUI::SetItemHotColor(DWORD dwColor)

{

m_dwItemHotColor = dwColor;

}

DWORD CTreeLayoutUI::GetItemHotColor() const

{

return m_dwItemHotColor;

}

void CTreeLayoutUI::SetItemSelectedColor(DWORD dwColor)

{

m_dwItemSelectedColor = dwColor;

}

DWORD CTreeLayoutUI::GetItemSelectedColor() const

{

return m_dwItemSelectedColor;

}

void CTreeLayoutUI::DrawItemBk(HDC hDC)

{

DWORD iBackColor = 0;

RECT rcHotItem = {0};

RECT rcSelectedItem = {0};

if (m_pUpHotItem && (m_pSelectedItem != m_pUpHotItem)){

rcHotItem = GetItemRect(m_pUpHotItem);

iBackColor = GetItemHotColor();

if ( iBackColor != 0 ) {

CRenderEngine::DrawColor(hDC, rcHotItem, GetAdjustColor(iBackColor));

}

if( !m_sItemHotImage.IsEmpty() ) {

if( !DrawImage(hDC, (LPCTSTR)m_sItemHotImage) ) m_sItemHotImage.Empty();

else return;

}

}

if (m_pSelectedItem){

iBackColor = GetItemSelectedColor();

rcSelectedItem = GetItemRect(m_pSelectedItem);

if ( iBackColor != 0 ) {

CRenderEngine::DrawColor(hDC, rcSelectedItem, GetAdjustColor(iBackColor));

}

if( !m_sItemSelectedImage.IsEmpty() ) {

if( !DrawImage(hDC, (LPCTSTR)m_sItemSelectedImage) ) m_sItemSelectedImage.Empty();

else return;

}

}

if( m_sBkImage.IsEmpty() ) {

if( !m_sBkImage.IsEmpty() ) {

if( !DrawImage(hDC, (LPCTSTR)m_sBkImage) ) m_sBkImage.Empty();

else return;

}

}

}

void CTreeLayoutUI::DoPaint(HDC hDC, const RECT& rcPaint)

{

DrawItemBk(hDC);

__super::DoPaint(hDC, rcPaint);

}

/*******************************************************************

* 函数名称: Add

* 功 能: 添加节点

* 参 数: pParent父节点,pControl需要添加的控件,bInsertLast是添加在父节点后还是前

* 返 回 值: 添加成功返回true,否则返回false

* 作 者: houbin

* 创建日期: 2012年6月29日星期五

*******************************************************************/

bool CTreeLayoutUI::Add(CTreeElementUI* pParent, CTreeElementUI * pControl, bool bInsertLast)

{

bool bRet = false;

do

{

if (NULL == pControl) break;

//查询自己节点中是否有子节点

{

CTreeChildElementUI * pChildElementUI = NULL;

for(int n = 0; n < pControl->GetCount(); n++){

pChildElementUI = static_cast<CTreeChildElementUI *>(pControl->GetItemAt(n)->GetInterface(kTreeChildElementInterface));

if(NULL != pChildElementUI) break;

}

if (NULL == pChildElementUI){

CTreeChildElementUI * pChild = NULL;

try{

pChildElementUI = new CTreeChildElementUI();

pControl->Add(pChildElementUI);

}

catch (...){

if (pChildElementUI){

delete pChildElementUI;

pChildElementUI = NULL;

break;

}

}

}

}

if (pParent){

//检查父控件是否有子控件对象

CTreeChildElementUI * pChildElementUI = NULL;

for(int n = 0; n < pParent->GetCount(); n++){

pChildElementUI = static_cast<CTreeChildElementUI *>(pParent->GetItemAt(n)->GetInterface(kTreeChildElementInterface));

if(NULL != pChildElementUI) break;

}

if (NULL == pChildElementUI){

break;

}

//添加子节点

if (bInsertLast){

bRet = pChildElementUI->Add(pControl);

}

else{

bRet = pChildElementUI->AddAt(pControl, 0);

}

}

else{

if (bInsertLast){

bRet = __super::Add(pControl);

}

else{

bRet = __super::AddAt(pControl, 0);

}

}

} while (0);

if (bRet){

//设置所有相关父节点的高度

if (pParent){

//设置缩进

CTreeChildElementUI * pChildElementUI = NULL;

for(int n = 0; n < pParent->GetCount(); n++){

pChildElementUI = static_cast<CTreeChildElementUI *>(pParent->GetItemAt(n)->GetInterface(kTreeChildElementInterface));

if(NULL != pChildElementUI) break;

}

if (pChildElementUI){

pChildElementUI->SetPadding(CRect(GetIndent(), 0, 0, 0));

}

while(pParent){

if (!IsExpand(pParent)) break;

int nHeight = pParent->GetFixedHeight() + pControl->GetFixedHeight();

pParent->SetFixedHeight(nHeight);

pParent = GetParentItem(pParent);

}

}

}

return bRet;

}

/*******************************************************************

* 函数名称: Remove

* 功 能: 删除指定节点

* 参 数: pControl要删除的节点,bDelete删除的时候是否把节点的内存数据也删除

* 返 回 值: 删除成功返回true,否则返回false

* 作 者: houbin

* 创建日期: 2012年6月29日星期五

*******************************************************************/

bool CTreeLayoutUI::Remove(CTreeElementUI* pControl, bool bDelete)

{

bool bRet = false;

do

{

if (pControl == NULL) break;

CControlUI * pParentControl = pControl->GetParent();

if (NULL == pParentControl) break;

if (static_cast<CTreeChildElementUI*>(pParentControl->GetInterface(kTreeChildElementInterface))){

CTreeChildElementUI * pChildElement = static_cast<CTreeChildElementUI*>(pParentControl->GetInterface(kTreeChildElementInterface));

int nDelHeight = pControl->GetFixedHeight();

if (bDelete){

bRet = pChildElement->Remove(pControl);

}

else{

bRet = pChildElement->Erase(pControl);

}

//设置父节点的高度

if (bRet){

CTreeElementUI * pParentElement = static_cast<CTreeElementUI*>(pChildElement->GetParent()->GetInterface(kTreeElementInterface));

while(pParentElement){

if (!IsExpand(pParentElement)) break;

int nHeight = pParentElement->GetFixedHeight() - nDelHeight;

pParentElement->SetFixedHeight(nHeight);

pParentElement = GetParentItem(pParentElement);

}

}

}

else if (static_cast<CTreeLayoutUI*>(pParentControl->GetInterface(kTreeLayoutInterface)) == this){

if (bDelete){

bRet = __super::Remove(pControl);

}

else{

bRet = __super::Erase(pControl);

}

}

m_pSelectedItem = NULL;

m_pUpHotItem = NULL;

} while (0);

return bRet;

}

/*******************************************************************

* 函数名称: RemoveAll

* 功 能: 删除树

* 参 数: 无

* 返 回 值: 无

* 作 者: houbin

* 创建日期: 2012年6月29日星期五

*******************************************************************/

void CTreeLayoutUI::RemoveAll()

{

__super::RemoveAll();

m_pSelectedItem = NULL;

m_pUpHotItem = NULL;

}

/*******************************************************************

* 函数名称: GetRootItem

* 功 能: 获取跟节点

* 参 数: 无

* 返 回 值: 返回根节点指针

* 作 者: houbin

* 创建日期: 2012年7月2日星期一

*******************************************************************/

CTreeElementUI * CTreeLayoutUI::GetRootItem()

{

CTreeElementUI * pElementUI = NULL;

for( int i = 0; i < GetCount(); i++ ) {

if( static_cast<CTreeElementUI*>(GetItemAt(i)->GetInterface(kTreeElementInterface)) != NULL ) {

pElementUI = static_cast<CTreeElementUI*>(GetItemAt(i)->GetInterface(kTreeElementInterface));

break;

}

}

return pElementUI;

}

/*******************************************************************

* 函数名称: GetNextItem

* 功 能: 获取下一个节点

* 参 数: 当前节点指针

* 返 回 值: 下一个节点指针

* 作 者: houbin

* 创建日期: 2012年7月2日星期一

*******************************************************************/

CTreeElementUI * CTreeLayoutUI::GetNextItem(CTreeElementUI * pElement)

{

CTreeElementUI * pElementRet = NULL;

do

{

if (NULL == pElement) break;

CContainerUI * pParentElement = static_cast<CContainerUI *>(pElement->GetParent());

if (NULL == pParentElement) break;

int nIndex = pParentElement->GetItemIndex(pElement);

for(int i = nIndex + 1; i < pParentElement->GetCount(); i++)

{

pElementRet = static_cast<CTreeElementUI *>(pParentElement->GetItemAt(i)->GetInterface(kTreeElementInterface));

if (pElementRet) break;

}

} while (0);

return pElementRet;

}

/*******************************************************************

* 函数名称: GetChildItem

* 功 能: 获取节点的子节点

* 参 数: pElement需要获取的子节点控件

* 返 回 值: 成功返回直接点指针,否则返回NULL

* 作 者: houbin

* 创建日期: 2012年6月29日星期五

*******************************************************************/

CTreeElementUI * CTreeLayoutUI::GetChildItem(CTreeElementUI * pElement)

{

CTreeElementUI * pElementRet = NULL;

do

{

if (NULL == pElement) break;

CTreeChildElementUI * pChildElementUI = NULL;

for(int n = 0; n < pElement->GetCount(); n++){

pChildElementUI = static_cast<CTreeChildElementUI *>(pElement->GetItemAt(n)->GetInterface(kTreeChildElementInterface));

if(NULL != pChildElementUI) break;

}

if (NULL == pChildElementUI) break;

if (pChildElementUI->GetCount() <= 0) break;

pElementRet = static_cast<CTreeElementUI*>(pChildElementUI->GetItemAt(0)->GetInterface(kTreeElementInterface));

} while (0);

return pElementRet;

}

//收缩节点

void CTreeLayoutUI::CollapseElement(CTreeElementUI * pElement)

{

do

{

if (NULL == pElement) break;

CTreeChildElementUI * pChildElement = NULL;

for(int n = 0; n < pElement->GetCount(); n++){

pChildElement = static_cast<CTreeChildElementUI *>(pElement->GetItemAt(n)->GetInterface(kTreeChildElementInterface));

if(NULL != pChildElement) break;

}

if (NULL == pChildElement) break;

if (!IsExpand(pElement)) break;

pChildElement->SetVisible(false);

CTreeDataUI * pDataUI = pElement->GetDataElement();

if (pDataUI){

int nOldHeight = pElement->GetFixedHeight();

int nHeight = pDataUI->GetFixedHeight();

pElement->SetFixedHeight(nHeight);

//设置父节点的高度

CTreeElementUI * pParentElement = GetParentItem(pElement);

while(pParentElement)

{

//父节点展开,则设置展开的高度

if (IsExpand(pParentElement)){

int nParentHeight = pParentElement->GetFixedHeight() + nHeight - nOldHeight;

pParentElement->SetFixedHeight(nParentHeight);

}

pParentElement = GetParentItem(pParentElement);

}

//设置父节点高度完毕////////////

}

} while (0);

}

//展开节点

void CTreeLayoutUI::ExpandElement(CTreeElementUI * pElement)

{

do

{

if (NULL == pElement) break;

CTreeChildElementUI * pChildElement = NULL;

for(int n = 0; n < pElement->GetCount(); n++){

pChildElement = static_cast<CTreeChildElementUI *>(pElement->GetItemAt(n)->GetInterface(kTreeChildElementInterface));

if(NULL != pChildElement) break;

}

if (NULL == pChildElement) break;

if (IsExpand(pElement)) break;

pChildElement->SetVisible(true);

CTreeDataUI * pDataUI = pElement->GetDataElement();

if (pDataUI){

int nOldHeight = pElement->GetFixedHeight();

int nHeight = pDataUI->GetFixedHeight();

CTreeElementUI * pChildNode = GetChildItem(pElement);

while(pChildNode)

{

nHeight += pChildNode->GetFixedHeight();

pChildNode = GetNextItem(pChildNode);

}

pElement->SetFixedHeight(nHeight);

//设置父节点的高度

CTreeElementUI * pParentElement = GetParentItem(pElement);

while(pParentElement)

{

//父节点展开,则设置展开的高度

if (IsExpand(pParentElement)){

int nParentHeight = pParentElement->GetFixedHeight() + nHeight - nOldHeight;

pParentElement->SetFixedHeight(nParentHeight);

}

pParentElement = GetParentItem(pParentElement);

}

//设置父节点高度完毕////////////

}

} while (0);

}

void CTreeLayoutUI::Expand(CTreeElementUI * pElement, UINT nCode)

{

do

{

if (NULL == pElement) break;

CTreeChildElementUI * pChildElement = NULL;

for(int n = 0; n < pElement->GetCount(); n++){

pChildElement = static_cast<CTreeChildElementUI *>(pElement->GetItemAt(n)->GetInterface(kTreeChildElementInterface));

if(NULL != pChildElement) break;

}

if (NULL == pChildElement) break;

if (TVE_COLLAPSE == nCode){

CollapseElement(pElement);

}

if(TVE_EXPAND == nCode){

ExpandElement(pElement);

}

if(TVE_TOGGLE == nCode){

//如果是收缩则展开,如果展开则收缩

if (IsExpand(pElement)){

CollapseElement(pElement);

}

else{

ExpandElement(pElement);

}

}

} while (0);

}

/*******************************************************************

* 函数名称: IsExpand

* 功 能: 检测指定节点是否展开

* 参 数: pElement节点

* 返 回 值: true为展开,false为没有展开

* 作 者: houbin

* 创建日期: 2012年7月2日星期一

*******************************************************************/

bool CTreeLayoutUI::IsExpand(CTreeElementUI * pElement)

{

bool bRet = false;

do

{

if (NULL == pElement) break;

CTreeChildElementUI * pChildElement = NULL;

for(int n = 0; n < pElement->GetCount(); n++){

pChildElement = static_cast<CTreeChildElementUI *>(pElement->GetItemAt(n)->GetInterface(kTreeChildElementInterface));

if(NULL != pChildElement) break;

}

if (NULL == pChildElement) break;

bRet = pChildElement->GetVisible();

} while (0);

return bRet;

}

bool CTreeLayoutUI::ItemHasChildren(CTreeElementUI * pElement)

{

bool bRet = false;

if (GetChildItem(pElement))

{

bRet = true;

}

return bRet;

}

void CTreeLayoutUI::SelectItem(CTreeElementUI * pElement, UINT nCode)

{

}

CTreeElementUI * CTreeLayoutUI::GetSelectedItem()

{

return m_pSelectedItem;

}

CTreeElementUI * CTreeLayoutUI::GetParentItem(CTreeElementUI * pElement)

{

CTreeElementUI * pElementRet = NULL;

do

{

if (NULL == pElement) break;

CControlUI * pParent = pElement->GetParent();

if (pParent && (pParent = pParent->GetParent())){

pElementRet = static_cast<CTreeElementUI*>(pParent->GetInterface(kTreeElementInterface));

}

} while (0);

return pElementRet;

}

CTreeElementUI * CTreeLayoutUI::HitTest(POINT pt)

{

CTreeElementUI * pElementRet = NULL;

CControlUI * pControl = GetManager()->FindSubControlByPoint(this, pt);

while(pControl)

{

if (pControl->GetInterface(kTreeLayoutInterface)){

break;

}

else if (pControl->GetInterface(kTreeChildElementInterface)){

break;

}

else if (pControl->GetInterface(kTreeElementInterface)){

pElementRet = static_cast<CTreeElementUI *>(pControl->GetInterface(kTreeElementInterface));

break;

}

else{

pControl = pControl->GetParent();

}

}

return pElementRet;

}

RECT CTreeLayoutUI::GetItemRect(CTreeElementUI * pElement)

{

RECT rcItem = {0};

RECT rc = {0};

do

{

if (NULL == pElement) break;

CTreeDataUI * pDataUI = NULL;

for (int i = 0; i < pElement->GetCount(); i++){

pDataUI = static_cast<CTreeDataUI *>(pElement->GetItemAt(i)->GetInterface(kTreeDataInterface));

if (pDataUI) break;

}

if (NULL == pDataUI) break;

rc = GetPos();

rcItem = pDataUI->GetPos();

rcItem.left = rc.left;

} while (0);

return rcItem;

}

void CTreeLayoutUI::QuickSort(CContainerUI * pElement, TREESORTPROC pSortProc, int nFirst, int nEnd)

{

int i = nFirst;

int j = nEnd;

do

{

CTreeElementUI * pControlFirst = NULL;

CTreeElementUI * pControlEnd = NULL;

CTreeElementUI * pKeyControl = NULL;

if (NULL == pElement) break;

if (NULL == pSortProc) break;

pKeyControl = static_cast<CTreeElementUI *>(pElement->GetItemAt(nFirst));

if (NULL == pKeyControl) break;

if (nEnd >= pElement->GetCount()) break;

while(i < j)

{

//从右往左,把右边最小的数据放在最前面

while( (i < j) && (pSortProc(pKeyControl, static_cast<CTreeElementUI *>(pElement->GetItemAt(j)), this) <= 0) ) j--;

pControlFirst = static_cast<CTreeElementUI *>(pElement->GetItemAt(i));

pControlEnd = static_cast<CTreeElementUI *>(pElement->GetItemAt(j));

if (pControlFirst && pControlEnd){

pElement->Erase(pControlEnd);

pElement->AddAt(pControlEnd, i);

pElement->Erase(pControlFirst);

pElement->AddAt(pControlFirst, j);

}

//从左往右,把左边最大的值放在最右边

while( (i < j) && (pSortProc(static_cast<CTreeElementUI *>(pElement->GetItemAt(i)), pKeyControl, this) <= 0) ) i++;

pControlFirst = static_cast<CTreeElementUI *>(pElement->GetItemAt(i));

pControlEnd = static_cast<CTreeElementUI *>(pElement->GetItemAt(j));

if (pControlFirst && pControlEnd){

pElement->Erase(pControlEnd);

pElement->AddAt(pControlEnd, i);

pElement->Erase(pControlFirst);

pElement->AddAt(pControlFirst, j);

}

}

//把KEY插入到中间

pControlFirst = static_cast<CTreeElementUI *>(pElement->GetItemAt(i));

if (pControlFirst){

int nIndex = pElement->GetItemIndex(pKeyControl);

if (nIndex != i){

pElement->Erase(pKeyControl);

pElement->AddAt(pKeyControl, i);

pElement->Erase(pControlFirst);

pElement->AddAt(pControlFirst, nIndex);

}

}

if (nFirst < i-1) QuickSort(pElement, pSortProc, nFirst, i-1);//对左侧分区域进行快速排序

if (i+1 < nEnd) QuickSort(pElement, pSortProc, i+1, nEnd);//对右侧分区域进行快速排序

} while (0);

}

void CTreeLayoutUI::SortChildren(CContainerUI * pElement, TREESORTPROC pSortProc)

{

if (pElement)

{

CTreeElementUI * pNode = static_cast<CTreeElementUI *>(pElement->GetInterface(kTreeElementInterface));

if (pNode){

CTreeChildElementUI * pChildElement = NULL;

for (int i = 0; i < pElement->GetCount(); i++){

pChildElement = static_cast<CTreeChildElementUI *>(pElement->GetItemAt(i)->GetInterface(kTreeChildElementInterface));

if (pChildElement) break;

}

if (pChildElement){

QuickSort(pChildElement, pSortProc, 0, pChildElement->GetCount() - 1);

}

}

else{

CTreeLayoutUI * pTreeLayout = static_cast<CTreeLayoutUI *>(pElement->GetInterface(kTreeLayoutInterface));

if (pTreeLayout){

QuickSort(pTreeLayout, pSortProc, 0, pTreeLayout->GetCount() - 1);

}

}

Invalidate();

}

}

void CTreeLayoutUI::SetIndent(int nIndentation)

{

m_nIndentation = nIndentation;

}

int CTreeLayoutUI::GetIndent()

{

return m_nIndentation;

}

}

修改DUILIB的CContainerUI,添加下面两个接口

bool CContainerUI::Erase(CControlUI* pControl)

{

if( pControl == NULL) return false;

for( int it = 0; it < m_items.GetSize(); it++ ) {

if( static_cast<CControlUI*>(m_items[it]) == pControl ) {

NeedUpdate();

return m_items.Remove(it);

}

}

return false;

}

bool CContainerUI::Erase(int iIndex)

{

CControlUI* pControl = GetItemAt(iIndex);

if (pControl != NULL) {

return CContainerUI::Erase(pControl);

}

return false;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐