Add theming for treeview control.
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index 1aa8c67..ac01889 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 @@
#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 @@
{
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 @@
/* 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 @@
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 @@
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 @@
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 @@
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 @@
case WM_TIMER:
return TREEVIEW_HandleTimer(infoPtr, wParam);
+ case WM_THEMECHANGED:
+ return theme_changed (infoPtr);
+
case WM_VSCROLL:
return TREEVIEW_VScroll(infoPtr, wParam);