From 171fea006dc200dc8a3e38621fa88d4a37bb6595 Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Thu, 28 Jul 2005 10:15:10 +0000 Subject: [PATCH] Add theming for treeview control. --- dlls/comctl32/treeview.c | 152 +++++++++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 39 deletions(-) diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index 1aa8c678d4e..ac01889bf75 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c @@ -59,6 +59,8 @@ #include "winnls.h" #include "commctrl.h" #include "comctl32.h" +#include "uxtheme.h" +#include "tmschema.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -196,6 +198,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(treeview); #define ISVISIBLE(x) ((x)->visibleOrder >= 0) +static const WCHAR themeClass[] = { 'T','r','e','e','v','i','e','w',0 }; + + typedef VOID (*TREEVIEW_ItemEnumFunc)(TREEVIEW_INFO *, TREEVIEW_ITEM *,LPVOID); @@ -2361,45 +2366,58 @@ TREEVIEW_DrawItemLines(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item) { if (item->cChildren) { - LONG height = item->rect.bottom - item->rect.top; - LONG width = item->stateOffset - item->linesOffset; - LONG rectsize = min(height, width) / 4; - /* plussize = ceil(rectsize * 3/4) */ - LONG plussize = (rectsize + 1) * 3 / 4; - - HPEN hNewPen = CreatePen(PS_SOLID, 0, infoPtr->clrLine); - HPEN hOldPen = SelectObject(hdc, hNewPen); - - Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1, - centerx + rectsize + 2, centery + rectsize + 2); - - SelectObject(hdc, hOldPen); - DeleteObject(hNewPen); - - if (height < 18 || width < 18) - { - MoveToEx(hdc, centerx - plussize + 1, centery, NULL); - LineTo(hdc, centerx + plussize, centery); - - if (!(item->state & TVIS_EXPANDED)) - { - MoveToEx(hdc, centerx, centery - plussize + 1, NULL); - LineTo(hdc, centerx, centery + plussize); - } - } - else - { - Rectangle(hdc, centerx - plussize + 1, centery - 1, - centerx + plussize, centery + 2); - - if (!(item->state & TVIS_EXPANDED)) - { - Rectangle(hdc, centerx - 1, centery - plussize + 1, - centerx + 2, centery + plussize); - SetPixel(hdc, centerx - 1, centery, infoPtr->clrBk); - SetPixel(hdc, centerx + 1, centery, infoPtr->clrBk); - } - } + HTHEME theme = GetWindowTheme(infoPtr->hwnd); + if (theme) + { + RECT glyphRect = item->rect; + glyphRect.left = item->linesOffset; + glyphRect.right = item->stateOffset; + DrawThemeBackground (theme, hdc, TVP_GLYPH, + (item->state & TVIS_EXPANDED) ? GLPS_OPENED : GLPS_CLOSED, + &glyphRect, NULL); + } + else + { + LONG height = item->rect.bottom - item->rect.top; + LONG width = item->stateOffset - item->linesOffset; + LONG rectsize = min(height, width) / 4; + /* plussize = ceil(rectsize * 3/4) */ + LONG plussize = (rectsize + 1) * 3 / 4; + + HPEN hNewPen = CreatePen(PS_SOLID, 0, infoPtr->clrLine); + HPEN hOldPen = SelectObject(hdc, hNewPen); + + Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1, + centerx + rectsize + 2, centery + rectsize + 2); + + SelectObject(hdc, hOldPen); + DeleteObject(hNewPen); + + if (height < 18 || width < 18) + { + MoveToEx(hdc, centerx - plussize + 1, centery, NULL); + LineTo(hdc, centerx + plussize, centery); + + if (!(item->state & TVIS_EXPANDED)) + { + MoveToEx(hdc, centerx, centery - plussize + 1, NULL); + LineTo(hdc, centerx, centery + plussize); + } + } + else + { + Rectangle(hdc, centerx - plussize + 1, centery - 1, + centerx + plussize, centery + 2); + + if (!(item->state & TVIS_EXPANDED)) + { + Rectangle(hdc, centerx - 1, centery - plussize + 1, + centerx + 2, centery + plussize); + SetPixel(hdc, centerx - 1, centery, infoPtr->clrBk); + SetPixel(hdc, centerx + 1, centery, infoPtr->clrBk); + } + } + } } } SelectObject(hdc, hbrOld); @@ -4952,6 +4970,8 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) /* Make sure actual scrollbar state is consistent with uInternalStatus */ ShowScrollBar(hwnd, SB_VERT, FALSE); ShowScrollBar(hwnd, SB_HORZ, FALSE); + + OpenThemeData (hwnd, themeClass); return 0; } @@ -4971,9 +4991,12 @@ TREEVIEW_Destroy(TREEVIEW_INFO *infoPtr) SetWindowLongPtrW(infoPtr->hwndEdit, GWLP_WNDPROC, (DWORD_PTR)infoPtr->wpEditOrig); + CloseThemeData (GetWindowTheme (infoPtr->hwnd)); + /* Deassociate treeview from the window before doing anything drastic. */ SetWindowLongPtrW(infoPtr->hwnd, 0, (DWORD_PTR)NULL); + DeleteObject(infoPtr->hDefaultFont); DeleteObject(infoPtr->hBoldFont); DeleteObject(infoPtr->hUnderlineFont); @@ -5201,6 +5224,40 @@ TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, WPARAM wParam, LPARAM lParam) return 0; } +/* Draw themed border */ +static BOOL nc_paint (TREEVIEW_INFO *infoPtr, HRGN region) +{ + HTHEME theme = GetWindowTheme (infoPtr->hwnd); + HDC dc; + RECT r; + HRGN cliprgn; + int cxEdge = GetSystemMetrics (SM_CXEDGE), + cyEdge = GetSystemMetrics (SM_CYEDGE); + + if (!theme) return FALSE; + + GetWindowRect(infoPtr->hwnd, &r); + + cliprgn = CreateRectRgn (r.left + cxEdge, r.top + cyEdge, + r.right - cxEdge, r.bottom - cyEdge); + if (region != (HRGN)1) + CombineRgn (cliprgn, cliprgn, region, RGN_AND); + OffsetRect(&r, -r.left, -r.top); + + dc = GetDCEx(infoPtr->hwnd, region, DCX_WINDOW|DCX_INTERSECTRGN); + OffsetRect(&r, -r.left, -r.top); + + if (IsThemeBackgroundPartiallyTransparent (theme, 0, 0)) + DrawThemeParentBackground(infoPtr->hwnd, dc, &r); + DrawThemeBackground (theme, dc, 0, 0, &r, 0); + ReleaseDC(infoPtr->hwnd, dc); + + /* Call default proc to get the scrollbars etc. painted */ + DefWindowProcW (infoPtr->hwnd, WM_NCPAINT, (WPARAM)cliprgn, 0); + + return TRUE; +} + static LRESULT TREEVIEW_Notify(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { @@ -5346,6 +5403,15 @@ TREEVIEW_KillFocus(TREEVIEW_INFO *infoPtr) return 0; } +/* update theme after a WM_THEMECHANGED message */ +static LRESULT theme_changed (TREEVIEW_INFO* infoPtr) +{ + HTHEME theme = GetWindowTheme (infoPtr->hwnd); + CloseThemeData (theme); + OpenThemeData (infoPtr->hwnd, themeClass); + return 0; +} + static LRESULT WINAPI TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -5551,6 +5617,11 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) else return 0; + case WM_NCPAINT: + if (nc_paint (infoPtr, (HRGN)wParam)) + return 0; + goto def; + case WM_NOTIFY: return TREEVIEW_Notify(infoPtr, wParam, lParam); @@ -5590,6 +5661,9 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_TIMER: return TREEVIEW_HandleTimer(infoPtr, wParam); + case WM_THEMECHANGED: + return theme_changed (infoPtr); + case WM_VSCROLL: return TREEVIEW_VScroll(infoPtr, wParam);