From cec8b6b014db38d619de54fce8e3fd9f81bb8c88 Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Thu, 11 Aug 2005 18:34:45 +0000 Subject: [PATCH] Add theming for status bar control. --- dlls/comctl32/status.c | 138 +++++++++++++++++++++++++++++++++++------ 1 file changed, 119 insertions(+), 19 deletions(-) diff --git a/dlls/comctl32/status.c b/dlls/comctl32/status.c index 68672aafe53..61f1c348dad 100644 --- a/dlls/comctl32/status.c +++ b/dlls/comctl32/status.c @@ -51,6 +51,8 @@ #include "winnls.h" #include "commctrl.h" #include "comctl32.h" +#include "uxtheme.h" +#include "tmschema.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(statusbar); @@ -94,6 +96,8 @@ typedef struct #define VERT_BORDER 2 #define HORZ_GAP 2 +const static WCHAR themeClass[] = { 'S','t','a','t','u','s',0 }; + /* prototype */ static void STATUSBAR_SetPartBounds (STATUS_INFO *infoPtr); @@ -104,13 +108,28 @@ static inline LPCSTR debugstr_t(LPCWSTR text, BOOL isW) } static void -STATUSBAR_DrawSizeGrip (HDC hdc, LPRECT lpRect) +STATUSBAR_DrawSizeGrip (HTHEME theme, HDC hdc, LPRECT lpRect) { HPEN hPenFace, hPenShadow, hPenHighlight, hOldPen; POINT pt; INT i; 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.y = lpRect->bottom - 1; @@ -153,6 +172,8 @@ STATUSBAR_DrawPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, int i { RECT r = part->bound; 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); if (part->style & SBT_POPOUT) @@ -160,7 +181,15 @@ STATUSBAR_DrawPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, int i else if (part->style & SBT_NOBORDERS) 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) { DRAWITEMSTRUCT dis; @@ -190,6 +219,7 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in { HBRUSH hbrBk; HFONT hOldFont; + HTHEME theme; TRACE("item %d\n", itemID); if (!IsWindowVisible (infoPtr->Self)) @@ -197,11 +227,22 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in if (part->bound.right < part->bound.left) return; - if (infoPtr->clrBk != CLR_DEFAULT) - hbrBk = CreateSolidBrush (infoPtr->clrBk); + if ((theme = GetWindowTheme (infoPtr->Self))) + { + RECT cr; + GetClientRect (infoPtr->Self, &cr); + DrawThemeBackground(theme, hdc, 0, 0, &cr, &part->bound); + } 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); @@ -209,14 +250,11 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in SelectObject (hdc, hOldFont); - if (infoPtr->clrBk != CLR_DEFAULT) - DeleteObject (hbrBk); - if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) { RECT 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) RECT rect; HBRUSH hbrBk; HFONT hOldFont; + HTHEME theme; TRACE("\n"); if (!IsWindowVisible(infoPtr->Self)) @@ -237,11 +276,20 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc) GetClientRect (infoPtr->Self, &rect); - if (infoPtr->clrBk != CLR_DEFAULT) - hbrBk = CreateSolidBrush (infoPtr->clrBk); + if ((theme = GetWindowTheme (infoPtr->Self))) + { + DrawThemeBackground(theme, hdc, 0, 0, &rect, NULL); + } 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); @@ -255,11 +303,8 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc) SelectObject (hdc, hOldFont); - if (infoPtr->clrBk != CLR_DEFAULT) - DeleteObject (hbrBk); - if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) - STATUSBAR_DrawSizeGrip (hdc, &rect); + STATUSBAR_DrawSizeGrip (theme, hdc, &rect); return 0; } @@ -570,9 +615,26 @@ STATUSBAR_SetMinHeight (STATUS_INFO *infoPtr, INT height) if (IsWindowVisible (infoPtr->Self)) { INT width, x, y; RECT parent_rect; + HTHEME theme; GetClientRect (infoPtr->Notify, &parent_rect); 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; x = parent_rect.left; y = parent_rect.bottom - infoPtr->height; @@ -820,6 +882,8 @@ STATUSBAR_WMDestroy (STATUS_INFO *infoPtr) if (infoPtr->hwndToolTip) DestroyWindow (infoPtr->hwndToolTip); + CloseThemeData (GetWindowTheme (infoPtr->Self)); + SetWindowLongPtrW(infoPtr->Self, 0, 0); Free (infoPtr); return 0; @@ -879,6 +943,8 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate) infoPtr->parts[0].x = -1; infoPtr->parts[0].style = 0; infoPtr->parts[0].hIcon = 0; + + OpenThemeData (hwnd, themeClass); if (IsWindowUnicode (hwnd)) { infoPtr->bUnicode = TRUE; @@ -901,11 +967,15 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate) } dwStyle = GetWindowLongW (hwnd, GWL_STYLE); + /* native seems to clear WS_BORDER, too */ + dwStyle &= ~WS_BORDER; /* statusbars on managed windows should not have SIZEGRIP style */ if ((dwStyle & SBARS_SIZEGRIP) && lpCreate->hwndParent && 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))) { TEXTMETRICW tm; @@ -940,9 +1010,26 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate) } if (!(dwStyle & CCS_NORESIZE)) { /* don't resize wnd if it doesn't want it ! */ + HTHEME theme; GetClientRect (infoPtr->Notify, &rect); width = rect.right - rect.left; 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, width, infoPtr->height, SWP_NOZORDER); STATUSBAR_SetPartBounds (infoPtr); @@ -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 STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd) { @@ -1264,6 +1361,9 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (STATUSBAR_WMSize (infoPtr, (WORD)wParam)) return 0; return DefWindowProcW (hwnd, msg, wParam, lParam); + case WM_THEMECHANGED: + return theme_changed (infoPtr); + default: if ((msg >= WM_USER) && (msg < WM_APP)) ERR("unknown msg %04x wp=%04x lp=%08lx\n",