因为公司项目需要,对CTreeCtrl类进行了重载。效果如图
代码如下:
#pragma once
#include "afxcmn.h"
class COwnerDrawTree :
public CTreeCtrl
{
public:
COwnerDrawTree(void);
~COwnerDrawTree(void);
void DrawItems( CDC* pDC );
protected:
DECLARE_MESSAGE_MAP()
afx_msg void OnPaint();
afx_msg void OnNMClick(NMHDR *pNMHDR, LRESULT *pResult);
private:
CBitmap m_bmpParentItem;
};
#include "StdAfx.h"
#include "OwnerDrawTree.h"
#include "Resource.h"
COwnerDrawTree::COwnerDrawTree(void)
{
m_bmpParentItem.LoadBitmap(IDB_BITMAP1);
}
COwnerDrawTree::~COwnerDrawTree(void)
{
m_bmpParentItem.DeleteObject();
}
BEGIN_MESSAGE_MAP(COwnerDrawTree, CTreeCtrl)
ON_WM_PAINT()
ON_NOTIFY_REFLECT(NM_CLICK, &COwnerDrawTree::OnNMClick)
END_MESSAGE_MAP()
void COwnerDrawTree::OnPaint()
{
CPaintDC dc(this);
CDC memDC;
CBitmap bm_ff;
CBitmap *bm_old;
CFont *font, *old_font;
CFont fontDC;
int old_mode;
CRect rcClient;
GetClientRect(&rcClient);
memDC.CreateCompatibleDC( &dc );
bm_ff.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() );
// Select the bitmap into the off-screen DC.
bm_old = (CBitmap *)memDC.SelectObject( &bm_ff );
CBrush bshTmp(RGB(255,255,255));
memDC.FillRect(&rcClient, &bshTmp);
font = GetFont();
old_font = memDC.SelectObject( font );
// We're going to draw text transparently
old_mode = memDC.SetBkMode( TRANSPARENT );
DrawItems( &memDC );
dc.BitBlt( 0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
memDC.SelectObject( old_font );
memDC.SetBkMode( old_mode );
memDC.SelectObject( bm_old );
}
void COwnerDrawTree::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
HTREEITEM hItem = GetSelectedItem();
TRACE(L"%d/n", hItem);
*pResult = 0;
}
void COwnerDrawTree::DrawItems( CDC* pDC )
{
HTREEITEM hItem = GetFirstVisibleItem();
if ( hItem == NULL )
return;
do
{
CRect rcClient;
CRect rcItem;
CRect rcText;
GetClientRect(&rcClient);
GetItemRect(hItem, rcItem, TRUE);
rcText = rcItem;
// draw group background
HTREEITEM hParent = GetParentItem(hItem);
if (hParent == NULL)
{
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap *pbmpOld = memDC.SelectObject(&m_bmpParentItem);
pDC->StretchBlt(0, rcItem.top, rcClient.Width(), rcItem.Height(), &memDC, 0, 0, 4, 24, SRCCOPY);
memDC.SelectObject(pbmpOld);
// icon
UINT uState = GetItemState(hItem, TVIS_EXPANDED);
if ((uState & TVIS_EXPANDED) == TVIS_EXPANDED)
{
//::DrawIconEx(pDC->GetSafeHdc(), rcText.left + 10, rcItem.top+4, m_hExpandIcon, m_sizeExpand.cx, m_sizeExpand.cy, 0, 0, DI_NORMAL);
}
else
{
//::DrawIconEx(pDC->GetSafeHdc(), rcText.left + 10, rcItem.top+4, m_hCollapseIcon, m_sizeExpand.cx, m_sizeExpand.cy, 0, 0, DI_NORMAL);
}
rcText = rcItem;
rcText.left += 30;
}
else
{
// draw selected item.
UINT nState = GetItemState(hItem, TVIS_SELECTED);
if (TVIS_SELECTED & nState)
{
CRect rcItemTmp = rcItem;
rcItemTmp.left = 0;
rcItemTmp.right = rcClient.right;
pDC->FillSolidRect(rcItemTmp, RGB(127,0,127));
}
}
// Draw image
int nImage = -1;
int nSelectedImage = -1;
BOOL bRet = GetItemImage(hItem, nImage, nSelectedImage);
CImageList *pImgList = GetImageList(TVSIL_NORMAL);
if (bRet && pImgList!=NULL)
{
IMAGEINFO ii;
pImgList->GetImageInfo(nImage, &ii);
CRect rcImage = ii.rcImage;
CRect rcItem;
GetItemRect(hItem, rcItem, FALSE);
int nImageTop = max(rcItem.top, rcItem.top + (rcItem.Height()-rcImage.Height()) / 2);
pImgList->Draw(pDC, nImage, CPoint(rcText.left - rcImage.Width()-2, nImageTop), ILD_TRANSPARENT);
}
// Draw text
/* CFont *pFontOld = NULL;
if (hParent == NULL)
{
CFont *pFontD = NULL;
GetTextFont(NULL, &pFontD);
pFontOld = pDC->SelectObject(pFontD);
}
else
{
CFont *pFontN = NULL;
GetTextFont(&pFontN, NULL);
pFontOld = pDC->SelectObject(pFontN);
}*/
rcText.right = rcClient.right;
pDC->SetBkMode(TRANSPARENT);
CString strText = GetItemText(hItem);
pDC->DrawText(strText, rcText, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_VCENTER);
//pDC->SelectObject(pFontOld);
} while ( (hItem = GetNextVisibleItem(hItem)) != NULL );
}