Commit cec8b6b0 authored by Frank Richter's avatar Frank Richter Committed by Alexandre Julliard

Add theming for status bar control.

parent a95e3e29
...@@ -51,6 +51,8 @@ ...@@ -51,6 +51,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/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(statusbar); WINE_DEFAULT_DEBUG_CHANNEL(statusbar);
...@@ -94,6 +96,8 @@ typedef struct ...@@ -94,6 +96,8 @@ typedef struct
#define VERT_BORDER 2 #define VERT_BORDER 2
#define HORZ_GAP 2 #define HORZ_GAP 2
const static WCHAR themeClass[] = { 'S','t','a','t','u','s',0 };
/* prototype */ /* prototype */
static void static void
STATUSBAR_SetPartBounds (STATUS_INFO *infoPtr); STATUSBAR_SetPartBounds (STATUS_INFO *infoPtr);
...@@ -104,13 +108,28 @@ static inline LPCSTR debugstr_t(LPCWSTR text, BOOL isW) ...@@ -104,13 +108,28 @@ static inline LPCSTR debugstr_t(LPCWSTR text, BOOL isW)
} }
static void static void
STATUSBAR_DrawSizeGrip (HDC hdc, LPRECT lpRect) STATUSBAR_DrawSizeGrip (HTHEME theme, HDC hdc, LPRECT lpRect)
{ {
HPEN hPenFace, hPenShadow, hPenHighlight, hOldPen; HPEN hPenFace, hPenShadow, hPenHighlight, hOldPen;
POINT pt; POINT pt;
INT i; INT i;
TRACE("draw size grip %ld,%ld - %ld,%ld\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); TRACE("draw size grip %ld,%ld - %ld,%ld\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
if (theme)
{
RECT gripperRect;
SIZE gripperSize;
gripperRect = *lpRect;
if (SUCCEEDED (GetThemePartSize (theme, hdc, SP_GRIPPER, 0, lpRect,
TS_DRAW, &gripperSize)))
{
gripperRect.left = gripperRect.right - gripperSize.cx;
gripperRect.top = gripperRect.bottom - gripperSize.cy;
if (SUCCEEDED (DrawThemeBackground(theme, hdc, SP_GRIPPER, 0, &gripperRect, NULL)))
return;
}
}
pt.x = lpRect->right - 1; pt.x = lpRect->right - 1;
pt.y = lpRect->bottom - 1; pt.y = lpRect->bottom - 1;
...@@ -153,6 +172,8 @@ STATUSBAR_DrawPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, int i ...@@ -153,6 +172,8 @@ STATUSBAR_DrawPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, int i
{ {
RECT r = part->bound; RECT r = part->bound;
UINT border = BDR_SUNKENOUTER; UINT border = BDR_SUNKENOUTER;
HTHEME theme = GetWindowTheme (infoPtr->Self);
int themePart = SP_PANE;
TRACE("part bound %ld,%ld - %ld,%ld\n", r.left, r.top, r.right, r.bottom); TRACE("part bound %ld,%ld - %ld,%ld\n", r.left, r.top, r.right, r.bottom);
if (part->style & SBT_POPOUT) if (part->style & SBT_POPOUT)
...@@ -160,7 +181,15 @@ STATUSBAR_DrawPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, int i ...@@ -160,7 +181,15 @@ STATUSBAR_DrawPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, int i
else if (part->style & SBT_NOBORDERS) else if (part->style & SBT_NOBORDERS)
border = 0; border = 0;
DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST); if (theme)
{
if ((GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP)
&& (infoPtr->simple || (itemID == (infoPtr->numParts-1))))
themePart = SP_GRIPPERPANE;
DrawThemeBackground(theme, hdc, themePart, 0, &r, NULL);
}
else
DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);
if (part->style & SBT_OWNERDRAW) { if (part->style & SBT_OWNERDRAW) {
DRAWITEMSTRUCT dis; DRAWITEMSTRUCT dis;
...@@ -190,6 +219,7 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in ...@@ -190,6 +219,7 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in
{ {
HBRUSH hbrBk; HBRUSH hbrBk;
HFONT hOldFont; HFONT hOldFont;
HTHEME theme;
TRACE("item %d\n", itemID); TRACE("item %d\n", itemID);
if (!IsWindowVisible (infoPtr->Self)) if (!IsWindowVisible (infoPtr->Self))
...@@ -197,11 +227,22 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in ...@@ -197,11 +227,22 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in
if (part->bound.right < part->bound.left) return; if (part->bound.right < part->bound.left) return;
if (infoPtr->clrBk != CLR_DEFAULT) if ((theme = GetWindowTheme (infoPtr->Self)))
hbrBk = CreateSolidBrush (infoPtr->clrBk); {
RECT cr;
GetClientRect (infoPtr->Self, &cr);
DrawThemeBackground(theme, hdc, 0, 0, &cr, &part->bound);
}
else else
hbrBk = GetSysColorBrush (COLOR_3DFACE); {
FillRect(hdc, &part->bound, hbrBk); if (infoPtr->clrBk != CLR_DEFAULT)
hbrBk = CreateSolidBrush (infoPtr->clrBk);
else
hbrBk = GetSysColorBrush (COLOR_3DFACE);
FillRect(hdc, &part->bound, hbrBk);
if (infoPtr->clrBk != CLR_DEFAULT)
DeleteObject (hbrBk);
}
hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont); hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);
...@@ -209,14 +250,11 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in ...@@ -209,14 +250,11 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in
SelectObject (hdc, hOldFont); SelectObject (hdc, hOldFont);
if (infoPtr->clrBk != CLR_DEFAULT)
DeleteObject (hbrBk);
if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) { if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) {
RECT rect; RECT rect;
GetClientRect (infoPtr->Self, &rect); GetClientRect (infoPtr->Self, &rect);
STATUSBAR_DrawSizeGrip (hdc, &rect); STATUSBAR_DrawSizeGrip (theme, hdc, &rect);
} }
} }
...@@ -228,6 +266,7 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc) ...@@ -228,6 +266,7 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc)
RECT rect; RECT rect;
HBRUSH hbrBk; HBRUSH hbrBk;
HFONT hOldFont; HFONT hOldFont;
HTHEME theme;
TRACE("\n"); TRACE("\n");
if (!IsWindowVisible(infoPtr->Self)) if (!IsWindowVisible(infoPtr->Self))
...@@ -237,11 +276,20 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc) ...@@ -237,11 +276,20 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc)
GetClientRect (infoPtr->Self, &rect); GetClientRect (infoPtr->Self, &rect);
if (infoPtr->clrBk != CLR_DEFAULT) if ((theme = GetWindowTheme (infoPtr->Self)))
hbrBk = CreateSolidBrush (infoPtr->clrBk); {
DrawThemeBackground(theme, hdc, 0, 0, &rect, NULL);
}
else else
hbrBk = GetSysColorBrush (COLOR_3DFACE); {
FillRect(hdc, &rect, hbrBk); if (infoPtr->clrBk != CLR_DEFAULT)
hbrBk = CreateSolidBrush (infoPtr->clrBk);
else
hbrBk = GetSysColorBrush (COLOR_3DFACE);
FillRect(hdc, &rect, hbrBk);
if (infoPtr->clrBk != CLR_DEFAULT)
DeleteObject (hbrBk);
}
hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont); hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);
...@@ -255,11 +303,8 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc) ...@@ -255,11 +303,8 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc)
SelectObject (hdc, hOldFont); SelectObject (hdc, hOldFont);
if (infoPtr->clrBk != CLR_DEFAULT)
DeleteObject (hbrBk);
if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP)
STATUSBAR_DrawSizeGrip (hdc, &rect); STATUSBAR_DrawSizeGrip (theme, hdc, &rect);
return 0; return 0;
} }
...@@ -570,9 +615,26 @@ STATUSBAR_SetMinHeight (STATUS_INFO *infoPtr, INT height) ...@@ -570,9 +615,26 @@ STATUSBAR_SetMinHeight (STATUS_INFO *infoPtr, INT height)
if (IsWindowVisible (infoPtr->Self)) { if (IsWindowVisible (infoPtr->Self)) {
INT width, x, y; INT width, x, y;
RECT parent_rect; RECT parent_rect;
HTHEME theme;
GetClientRect (infoPtr->Notify, &parent_rect); GetClientRect (infoPtr->Notify, &parent_rect);
infoPtr->height = height + infoPtr->verticalBorder; infoPtr->height = height + infoPtr->verticalBorder;
if ((theme = GetWindowTheme (infoPtr->Self)))
{
/* Determine bar height from theme such that the content area is
* 'height' pixels large */
HDC hdc = GetDC (infoPtr->Self);
RECT r;
memset (&r, 0, sizeof (r));
r.bottom = height;
if (SUCCEEDED(GetThemeBackgroundExtent (theme, hdc, SP_PANE, 0, &r, &r)))
{
infoPtr->height = r.bottom - r.top;
}
ReleaseDC (infoPtr->Self, hdc);
}
width = parent_rect.right - parent_rect.left; width = parent_rect.right - parent_rect.left;
x = parent_rect.left; x = parent_rect.left;
y = parent_rect.bottom - infoPtr->height; y = parent_rect.bottom - infoPtr->height;
...@@ -820,6 +882,8 @@ STATUSBAR_WMDestroy (STATUS_INFO *infoPtr) ...@@ -820,6 +882,8 @@ STATUSBAR_WMDestroy (STATUS_INFO *infoPtr)
if (infoPtr->hwndToolTip) if (infoPtr->hwndToolTip)
DestroyWindow (infoPtr->hwndToolTip); DestroyWindow (infoPtr->hwndToolTip);
CloseThemeData (GetWindowTheme (infoPtr->Self));
SetWindowLongPtrW(infoPtr->Self, 0, 0); SetWindowLongPtrW(infoPtr->Self, 0, 0);
Free (infoPtr); Free (infoPtr);
return 0; return 0;
...@@ -879,6 +943,8 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate) ...@@ -879,6 +943,8 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate)
infoPtr->parts[0].x = -1; infoPtr->parts[0].x = -1;
infoPtr->parts[0].style = 0; infoPtr->parts[0].style = 0;
infoPtr->parts[0].hIcon = 0; infoPtr->parts[0].hIcon = 0;
OpenThemeData (hwnd, themeClass);
if (IsWindowUnicode (hwnd)) { if (IsWindowUnicode (hwnd)) {
infoPtr->bUnicode = TRUE; infoPtr->bUnicode = TRUE;
...@@ -901,11 +967,15 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate) ...@@ -901,11 +967,15 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate)
} }
dwStyle = GetWindowLongW (hwnd, GWL_STYLE); dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
/* native seems to clear WS_BORDER, too */
dwStyle &= ~WS_BORDER;
/* statusbars on managed windows should not have SIZEGRIP style */ /* statusbars on managed windows should not have SIZEGRIP style */
if ((dwStyle & SBARS_SIZEGRIP) && lpCreate->hwndParent && if ((dwStyle & SBARS_SIZEGRIP) && lpCreate->hwndParent &&
GetPropA( lpCreate->hwndParent, "__wine_x11_managed" )) GetPropA( lpCreate->hwndParent, "__wine_x11_managed" ))
SetWindowLongW (hwnd, GWL_STYLE, dwStyle & ~SBARS_SIZEGRIP); dwStyle &= ~SBARS_SIZEGRIP;
SetWindowLongW (hwnd, GWL_STYLE, dwStyle);
if ((hdc = GetDC (hwnd))) { if ((hdc = GetDC (hwnd))) {
TEXTMETRICW tm; TEXTMETRICW tm;
...@@ -940,9 +1010,26 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate) ...@@ -940,9 +1010,26 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate)
} }
if (!(dwStyle & CCS_NORESIZE)) { /* don't resize wnd if it doesn't want it ! */ if (!(dwStyle & CCS_NORESIZE)) { /* don't resize wnd if it doesn't want it ! */
HTHEME theme;
GetClientRect (infoPtr->Notify, &rect); GetClientRect (infoPtr->Notify, &rect);
width = rect.right - rect.left; width = rect.right - rect.left;
infoPtr->height = textHeight + 4 + infoPtr->verticalBorder; infoPtr->height = textHeight + 4 + infoPtr->verticalBorder;
if ((theme = GetWindowTheme (hwnd)))
{
/* Determine bar height from theme such that the content area is
* textHeight pixels large */
HDC hdc = GetDC (hwnd);
RECT r;
memset (&r, 0, sizeof (r));
r.bottom = textHeight;
if (SUCCEEDED(GetThemeBackgroundExtent (theme, hdc, SP_PANE, 0, &r, &r)))
{
infoPtr->height = r.bottom - r.top;
}
ReleaseDC (hwnd, hdc);
}
SetWindowPos(hwnd, 0, lpCreate->x, lpCreate->y - 1, SetWindowPos(hwnd, 0, lpCreate->x, lpCreate->y - 1,
width, infoPtr->height, SWP_NOZORDER); width, infoPtr->height, SWP_NOZORDER);
STATUSBAR_SetPartBounds (infoPtr); STATUSBAR_SetPartBounds (infoPtr);
...@@ -1102,6 +1189,16 @@ STATUSBAR_WMSize (STATUS_INFO *infoPtr, WORD flags) ...@@ -1102,6 +1189,16 @@ STATUSBAR_WMSize (STATUS_INFO *infoPtr, WORD flags)
} }
/* update theme after a WM_THEMECHANGED message */
static LRESULT theme_changed (STATUS_INFO* infoPtr)
{
HTHEME theme = GetWindowTheme (infoPtr->Self);
CloseThemeData (theme);
OpenThemeData (infoPtr->Self, themeClass);
return 0;
}
static LRESULT static LRESULT
STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd) STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd)
{ {
...@@ -1264,6 +1361,9 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -1264,6 +1361,9 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
if (STATUSBAR_WMSize (infoPtr, (WORD)wParam)) return 0; if (STATUSBAR_WMSize (infoPtr, (WORD)wParam)) return 0;
return DefWindowProcW (hwnd, msg, wParam, lParam); return DefWindowProcW (hwnd, msg, wParam, lParam);
case WM_THEMECHANGED:
return theme_changed (infoPtr);
default: default:
if ((msg >= WM_USER) && (msg < WM_APP)) if ((msg >= WM_USER) && (msg < WM_APP))
ERR("unknown msg %04x wp=%04x lp=%08lx\n", ERR("unknown msg %04x wp=%04x lp=%08lx\n",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment