Add theming for treeview control.

This commit is contained in:
Frank Richter 2005-07-28 10:15:10 +00:00 committed by Alexandre Julliard
parent c952f08ba8
commit 171fea006d
1 changed files with 113 additions and 39 deletions

View File

@ -59,6 +59,8 @@
#include "winnls.h" #include "winnls.h"
#include "commctrl.h" #include "commctrl.h"
#include "comctl32.h" #include "comctl32.h"
#include "uxtheme.h"
#include "tmschema.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -196,6 +198,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(treeview);
#define ISVISIBLE(x) ((x)->visibleOrder >= 0) #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); 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) if (item->cChildren)
{ {
LONG height = item->rect.bottom - item->rect.top; HTHEME theme = GetWindowTheme(infoPtr->hwnd);
LONG width = item->stateOffset - item->linesOffset; if (theme)
LONG rectsize = min(height, width) / 4; {
/* plussize = ceil(rectsize * 3/4) */ RECT glyphRect = item->rect;
LONG plussize = (rectsize + 1) * 3 / 4; glyphRect.left = item->linesOffset;
glyphRect.right = item->stateOffset;
HPEN hNewPen = CreatePen(PS_SOLID, 0, infoPtr->clrLine); DrawThemeBackground (theme, hdc, TVP_GLYPH,
HPEN hOldPen = SelectObject(hdc, hNewPen); (item->state & TVIS_EXPANDED) ? GLPS_OPENED : GLPS_CLOSED,
&glyphRect, NULL);
Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1, }
centerx + rectsize + 2, centery + rectsize + 2); else
{
SelectObject(hdc, hOldPen); LONG height = item->rect.bottom - item->rect.top;
DeleteObject(hNewPen); LONG width = item->stateOffset - item->linesOffset;
LONG rectsize = min(height, width) / 4;
if (height < 18 || width < 18) /* plussize = ceil(rectsize * 3/4) */
{ LONG plussize = (rectsize + 1) * 3 / 4;
MoveToEx(hdc, centerx - plussize + 1, centery, NULL);
LineTo(hdc, centerx + plussize, centery); HPEN hNewPen = CreatePen(PS_SOLID, 0, infoPtr->clrLine);
HPEN hOldPen = SelectObject(hdc, hNewPen);
if (!(item->state & TVIS_EXPANDED))
{ Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1,
MoveToEx(hdc, centerx, centery - plussize + 1, NULL); centerx + rectsize + 2, centery + rectsize + 2);
LineTo(hdc, centerx, centery + plussize);
} SelectObject(hdc, hOldPen);
} DeleteObject(hNewPen);
else
{ if (height < 18 || width < 18)
Rectangle(hdc, centerx - plussize + 1, centery - 1, {
centerx + plussize, centery + 2); MoveToEx(hdc, centerx - plussize + 1, centery, NULL);
LineTo(hdc, centerx + plussize, centery);
if (!(item->state & TVIS_EXPANDED))
{ if (!(item->state & TVIS_EXPANDED))
Rectangle(hdc, centerx - 1, centery - plussize + 1, {
centerx + 2, centery + plussize); MoveToEx(hdc, centerx, centery - plussize + 1, NULL);
SetPixel(hdc, centerx - 1, centery, infoPtr->clrBk); LineTo(hdc, centerx, centery + plussize);
SetPixel(hdc, centerx + 1, centery, infoPtr->clrBk); }
} }
} 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); SelectObject(hdc, hbrOld);
@ -4952,6 +4970,8 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
/* Make sure actual scrollbar state is consistent with uInternalStatus */ /* Make sure actual scrollbar state is consistent with uInternalStatus */
ShowScrollBar(hwnd, SB_VERT, FALSE); ShowScrollBar(hwnd, SB_VERT, FALSE);
ShowScrollBar(hwnd, SB_HORZ, FALSE); ShowScrollBar(hwnd, SB_HORZ, FALSE);
OpenThemeData (hwnd, themeClass);
return 0; return 0;
} }
@ -4971,9 +4991,12 @@ TREEVIEW_Destroy(TREEVIEW_INFO *infoPtr)
SetWindowLongPtrW(infoPtr->hwndEdit, GWLP_WNDPROC, SetWindowLongPtrW(infoPtr->hwndEdit, GWLP_WNDPROC,
(DWORD_PTR)infoPtr->wpEditOrig); (DWORD_PTR)infoPtr->wpEditOrig);
CloseThemeData (GetWindowTheme (infoPtr->hwnd));
/* Deassociate treeview from the window before doing anything drastic. */ /* Deassociate treeview from the window before doing anything drastic. */
SetWindowLongPtrW(infoPtr->hwnd, 0, (DWORD_PTR)NULL); SetWindowLongPtrW(infoPtr->hwnd, 0, (DWORD_PTR)NULL);
DeleteObject(infoPtr->hDefaultFont); DeleteObject(infoPtr->hDefaultFont);
DeleteObject(infoPtr->hBoldFont); DeleteObject(infoPtr->hBoldFont);
DeleteObject(infoPtr->hUnderlineFont); DeleteObject(infoPtr->hUnderlineFont);
@ -5201,6 +5224,40 @@ TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, WPARAM wParam, LPARAM lParam)
return 0; 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 static LRESULT
TREEVIEW_Notify(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) TREEVIEW_Notify(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{ {
@ -5346,6 +5403,15 @@ TREEVIEW_KillFocus(TREEVIEW_INFO *infoPtr)
return 0; 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 static LRESULT WINAPI
TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 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 else
return 0; return 0;
case WM_NCPAINT:
if (nc_paint (infoPtr, (HRGN)wParam))
return 0;
goto def;
case WM_NOTIFY: case WM_NOTIFY:
return TREEVIEW_Notify(infoPtr, wParam, lParam); return TREEVIEW_Notify(infoPtr, wParam, lParam);
@ -5590,6 +5661,9 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_TIMER: case WM_TIMER:
return TREEVIEW_HandleTimer(infoPtr, wParam); return TREEVIEW_HandleTimer(infoPtr, wParam);
case WM_THEMECHANGED:
return theme_changed (infoPtr);
case WM_VSCROLL: case WM_VSCROLL:
return TREEVIEW_VScroll(infoPtr, wParam); return TREEVIEW_VScroll(infoPtr, wParam);