#include "stdafx.h"
|
#include "ApredTreeCtrl2.h"
|
|
|
#define ROFFSET 7
|
#define WIDE 10
|
#define WIDE2 5
|
#define EXPANDED_WIDE 8
|
|
#define BADGE_HIDE 0
|
#define BADGE_DOT 1
|
#define BADGE_NUMBER 2
|
#define BADGE_DOT_WIDTH 12
|
#define BADGE_NUMBER_WIDTH 20
|
|
|
IMPLEMENT_DYNAMIC(CApredTreeCtrl2, CTreeCtrl)
|
|
CApredTreeCtrl2::CApredTreeCtrl2()
|
{
|
m_hBrushItem[0] = NULL;
|
m_hBrushItem[1] = NULL;
|
m_hBrushItem[2] = NULL;
|
m_crItemBk[0] = GetSysColor(COLOR_WINDOW);
|
m_crItemBk[1] = GetSysColor(COLOR_HIGHLIGHT);
|
m_crItemBk[2] = RGB(204, 206, 219);
|
m_crItemBtn[0] = RGB(30, 30, 30);
|
m_crItemBtn[1] = RGB(255, 255, 255);
|
m_crItemBtn[2] = RGB(255, 255, 255);
|
}
|
|
CApredTreeCtrl2::~CApredTreeCtrl2()
|
{
|
if (m_hBrushItem[0] != NULL) {
|
::DeleteObject(m_hBrushItem[0]);
|
}
|
if (m_hBrushItem[1] != NULL) {
|
::DeleteObject(m_hBrushItem[1]);
|
}
|
if (m_hBrushItem[2] != NULL) {
|
::DeleteObject(m_hBrushItem[2]);
|
}
|
}
|
|
BEGIN_MESSAGE_MAP(CApredTreeCtrl2, CTreeCtrl)
|
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CApredTreeCtrl2::OnNMCustomdraw)
|
END_MESSAGE_MAP()
|
|
|
void CApredTreeCtrl2::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
|
{
|
LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
|
LPNMTVCUSTOMDRAW lpnmcd = (LPNMTVCUSTOMDRAW)pNMCD;
|
HTREEITEM hItem;
|
UINT unt;
|
*pResult = 0;
|
|
|
switch (lpnmcd->nmcd.dwDrawStage)
|
{
|
case CDDS_PREPAINT:
|
*pResult = CDRF_NOTIFYITEMDRAW;
|
m_items.clear();
|
break;
|
|
case CDDS_ITEMPREPAINT:
|
m_items[(HTREEITEM)lpnmcd->nmcd.dwItemSpec] = lpnmcd->iLevel;
|
hItem = (HTREEITEM)lpnmcd->nmcd.dwItemSpec;
|
if (hItem != NULL) {
|
if ( (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED)== TVIS_SELECTED) {
|
if (GetFocus() != this) {
|
lpnmcd->clrTextBk = RGB(204, 206, 219);
|
}
|
}
|
}
|
*pResult = CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT; // ¶©ÔÄ»æÖƽáÊøÍ¨Öª
|
|
break;
|
|
|
case CDDS_ITEMPOSTPAINT: // Ïî»æÖÆ½áÊøÍ¨Öª
|
unt = GetIndent();
|
hItem = (HTREEITEM)lpnmcd->nmcd.dwItemSpec;
|
auto iter = m_items.find(hItem);
|
if (iter != m_items.end()) {
|
CRect button_rect = pNMCD->rc;
|
button_rect.right = button_rect.left + unt + 5;
|
int off = unt * iter->second;
|
button_rect.OffsetRect(off, 0);
|
DrawItemButton(hItem, pNMCD->hdc, &button_rect);
|
|
// ÊÇ·ñÓÐСԲµã
|
CRect rcItem = pNMCD->rc;
|
Gdiplus::Graphics graphics(pNMCD->hdc);
|
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
|
if (m_badges.find(hItem) != m_badges.end()) {
|
BADGE& badge = m_badges[hItem];
|
if (badge.type == BADGE_DOT) {
|
Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(badge.badgeBackground), GetGValue(badge.badgeBackground), GetBValue(badge.badgeBackground)));
|
int x = rcItem.right - 18 - BADGE_DOT_WIDTH;
|
int y = rcItem.top + (rcItem.Height() - BADGE_DOT_WIDTH) / 2;
|
graphics.FillEllipse(&brush, x, y, BADGE_DOT_WIDTH, BADGE_DOT_WIDTH);
|
}
|
else if (badge.type == BADGE_NUMBER) {
|
Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(badge.badgeBackground), GetGValue(badge.badgeBackground), GetBValue(badge.badgeBackground)));
|
int x = rcItem.right - 18 - BADGE_NUMBER_WIDTH;
|
int y = rcItem.top + (rcItem.Height() - BADGE_NUMBER_WIDTH) / 2;
|
graphics.FillEllipse(&brush, x, y, BADGE_NUMBER_WIDTH, BADGE_NUMBER_WIDTH);
|
RECT rcBadge;
|
rcBadge.left = x;
|
rcBadge.right = rcBadge.left + BADGE_NUMBER_WIDTH;
|
rcBadge.top = y;
|
rcBadge.bottom = rcBadge.top + BADGE_NUMBER_WIDTH;
|
::SetTextColor(pNMCD->hdc, badge.badgeForeground);
|
char szBuffer[32];
|
sprintf_s(szBuffer, 32, "%d%s", min(badge.number, 9), badge.number > 9 ? "+" : "");
|
DrawText(pNMCD->hdc, szBuffer, (int)strlen(szBuffer), &rcBadge, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
}
|
}
|
|
*pResult = CDRF_SKIPDEFAULT;
|
}
|
|
break;
|
}
|
}
|
|
void CApredTreeCtrl2::DrawItemButton(HTREEITEM hItem, HDC hDC, CRect* pRect)
|
{
|
if (!ItemHasChildren(hItem)) {
|
return;
|
}
|
|
|
// °´Å¥ÒªË¢Ò»ÏÂ
|
::FillRect(hDC, pRect, GetItemBkBrush(hItem));
|
if ((GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED) == TVIS_EXPANDED) {
|
int nBottomOffset = (pRect->Height() - EXPANDED_WIDE) / 2;
|
POINT pt[3];
|
pt[0].x = pRect->right - ROFFSET - EXPANDED_WIDE;
|
pt[0].y = pRect->bottom - nBottomOffset;
|
pt[1].x = pRect->right - ROFFSET;
|
pt[1].y = pRect->bottom - nBottomOffset;
|
pt[2].x = pRect->right - ROFFSET;
|
pt[2].y = pRect->bottom - nBottomOffset - EXPANDED_WIDE;
|
|
HBRUSH hBrush = GetItemBtnBrush(hItem);
|
HPEN hPen = GetItemBtnPen(hItem);
|
HBRUSH hOldBrush = (HBRUSH)::SelectObject(hDC, hBrush);
|
HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
|
::Polygon(hDC, pt, 3);
|
::SelectObject(hDC, hOldBrush);
|
::SelectObject(hDC, hOldPen);
|
::DeleteObject(hBrush);
|
::DeleteObject(hPen);
|
}
|
else {
|
int nBottomOffset = (pRect->Height() - WIDE) / 2;
|
POINT pt[3];
|
pt[0].x = pRect->right - ROFFSET - WIDE2;
|
pt[0].y = pRect->bottom - nBottomOffset - WIDE;
|
pt[1].x = pRect->right - ROFFSET - WIDE2;
|
pt[1].y = pRect->bottom - nBottomOffset;
|
pt[2].x = pRect->right - ROFFSET;
|
pt[2].y = pRect->bottom - nBottomOffset - WIDE2;
|
|
HBRUSH hBrush = GetItemBtnBrush(hItem);
|
HPEN hPen = GetItemBtnPen(hItem);
|
HBRUSH hOldBrush = (HBRUSH)::SelectObject(hDC, hBrush);
|
HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
|
::Polygon(hDC, pt, 3);
|
::SelectObject(hDC, hOldBrush);
|
::SelectObject(hDC, hOldPen);
|
::DeleteObject(hBrush);
|
::DeleteObject(hPen);
|
}
|
}
|
|
COLORREF CApredTreeCtrl2::SetBkColor(COLORREF crColor)
|
{
|
if (m_hBrushItem[0] != NULL) {
|
::DeleteObject(m_hBrushItem[0]);
|
}
|
m_hBrushItem[0] = CreateSolidBrush(crColor);
|
|
return CTreeCtrl::SetBkColor(crColor);
|
}
|
|
int CApredTreeCtrl2::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
{
|
if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
|
return -1;
|
|
m_crItemBk[0] = GetBkColor();
|
m_crItemBk[1] = GetSysColor(COLOR_HIGHLIGHT);
|
m_hBrushItem[0] = CreateSolidBrush(m_crItemBk[0]);
|
m_hBrushItem[1] = CreateSolidBrush(m_crItemBk[1]);
|
m_hBrushItem[2] = CreateSolidBrush(m_crItemBk[2]);
|
|
return 0;
|
}
|
|
HBRUSH CApredTreeCtrl2::GetItemBkBrush(HTREEITEM hItem)
|
{
|
BOOL bSelected = (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED) == TVIS_SELECTED;
|
BOOL bHilited = (GetItemState(hItem, TVIS_DROPHILITED) & TVIS_DROPHILITED) == TVIS_DROPHILITED;;
|
HTREEITEM hClickedItem = GetDropHilightItem();
|
|
|
if (bHilited) {
|
return m_hBrushItem[1];
|
}
|
|
if (!bSelected) {
|
return m_hBrushItem[0];
|
}
|
|
if (GetFocus() == this) {
|
if (hClickedItem == NULL) {
|
return m_hBrushItem[1];
|
}
|
else {
|
return m_hBrushItem[0];
|
}
|
}
|
|
|
return m_hBrushItem[2];
|
}
|
|
HBRUSH CApredTreeCtrl2::GetItemBtnBrush(HTREEITEM hItem)
|
{
|
BOOL bExpanded = (GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED) == TVIS_EXPANDED;
|
BOOL bSelected = (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED) == TVIS_SELECTED;
|
BOOL bHilited = (GetItemState(hItem, TVIS_DROPHILITED) & TVIS_DROPHILITED) == TVIS_DROPHILITED;;
|
HTREEITEM hClickedItem = GetDropHilightItem();
|
|
|
// Õ¹¿ªÊ±ÊµÐÄÈý½Ç
|
if (bExpanded) {
|
if (bHilited) {
|
return CreateSolidBrush(m_crItemBtn[1]);
|
}
|
|
if (!bSelected) {
|
return CreateSolidBrush(m_crItemBtn[0]);
|
}
|
|
if (GetFocus() == this && hClickedItem == NULL) {
|
return CreateSolidBrush(m_crItemBtn[1]);
|
}
|
|
return CreateSolidBrush(m_crItemBtn[0]);
|
}
|
else {
|
// ÊÕÆðʱ¿ÕÐÄÈý½Ç
|
if (bHilited) {
|
return CreateSolidBrush(m_crItemBk[1]);
|
}
|
|
if (!bSelected) {
|
return CreateSolidBrush(m_crItemBk[0]);
|
}
|
|
if (GetFocus() == this && hClickedItem == NULL) {
|
return CreateSolidBrush(m_crItemBk[1]);
|
}
|
|
return CreateSolidBrush(m_crItemBk[2]);
|
}
|
}
|
|
HPEN CApredTreeCtrl2::GetItemBtnPen(HTREEITEM hItem)
|
{
|
BOOL bExpanded = (GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED) == TVIS_EXPANDED;
|
BOOL bSelected = (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED) == TVIS_SELECTED;
|
BOOL bHilited = (GetItemState(hItem, TVIS_DROPHILITED) & TVIS_DROPHILITED) == TVIS_DROPHILITED;;
|
HTREEITEM hClickedItem = GetDropHilightItem();
|
|
|
// Õ¹¿ªÊ±ÊµÐÄÈý½Ç
|
if (bExpanded) {
|
if (bHilited) {
|
return CreatePen(PS_SOLID, 1, m_crItemBtn[1]);
|
}
|
|
if (!bSelected) {
|
return CreatePen(PS_SOLID, 1, m_crItemBtn[0]);
|
}
|
|
if (GetFocus() == this && hClickedItem == NULL) {
|
return CreatePen(PS_SOLID, 1, m_crItemBtn[1]);
|
}
|
|
return CreatePen(PS_SOLID, 1, m_crItemBtn[0]);
|
}
|
else {
|
// ÊÕÆðʱ¿ÕÐÄÈý½Ç
|
if (bHilited) {
|
return CreatePen(PS_SOLID, 1, m_crItemBtn[1]);
|
}
|
|
if (!bSelected) {
|
return CreatePen(PS_SOLID, 1, m_crItemBtn[0]);
|
}
|
|
if (GetFocus() == this && hClickedItem == NULL) {
|
return CreatePen(PS_SOLID, 1, m_crItemBtn[1]);
|
}
|
|
return CreatePen(PS_SOLID, 1, m_crItemBtn[0]);
|
}
|
}
|
|
void CApredTreeCtrl2::PreSubclassWindow()
|
{
|
m_crItemBk[0] = GetBkColor();
|
m_crItemBk[1] = GetSysColor(COLOR_HIGHLIGHT);
|
m_hBrushItem[0] = CreateSolidBrush(m_crItemBk[0]);
|
m_hBrushItem[1] = CreateSolidBrush(m_crItemBk[1]);
|
m_hBrushItem[2] = CreateSolidBrush(m_crItemBk[2]);
|
|
CTreeCtrl::PreSubclassWindow();
|
}
|
|
void CApredTreeCtrl2::SetItemBadge(HTREEITEM hItem, COLORREF badgeBackground, COLORREF badgeForeground)
|
{
|
if (m_badges.find(hItem) == m_badges.end()) {
|
BADGE badge;
|
badge.badgeBackground = badgeBackground;
|
badge.badgeForeground = badgeForeground;
|
badge.type = BADGE_HIDE;
|
m_badges[hItem] = badge;
|
}
|
else {
|
BADGE& badge = m_badges[hItem];
|
badge.badgeBackground = badgeBackground;
|
badge.badgeForeground = badgeForeground;
|
badge.type = BADGE_HIDE;
|
}
|
}
|
|
void CApredTreeCtrl2::ShowItemBadgeNumber(HTREEITEM hItem, int number)
|
{
|
if (m_badges.find(hItem) == m_badges.end()) {
|
return;
|
}
|
|
BADGE& badge = m_badges[hItem];
|
badge.type = BADGE_NUMBER;
|
badge.number = number;
|
InvalidateRect(NULL, TRUE);
|
}
|
|
void CApredTreeCtrl2::ShowItemBadgeDotMode(HTREEITEM hItem)
|
{
|
if (m_badges.find(hItem) == m_badges.end()) {
|
return;
|
}
|
|
BADGE& badge = m_badges[hItem];
|
if (badge.type != BADGE_DOT) {
|
badge.type = BADGE_DOT;
|
InvalidateRect(NULL, TRUE);
|
}
|
}
|
|
void CApredTreeCtrl2::HideItemBadge(HTREEITEM hItem)
|
{
|
if (m_badges.find(hItem) == m_badges.end()) {
|
return;
|
}
|
|
BADGE& badge = m_badges[hItem];
|
if (badge.type != BADGE_HIDE) {
|
badge.type = BADGE_HIDE;
|
InvalidateRect(NULL, TRUE);
|
}
|
}
|