Add theming for treeview control.
This commit is contained in:
parent
c952f08ba8
commit
171fea006d
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue