Add theming for status bar control.

This commit is contained in:
Frank Richter 2005-08-11 18:34:45 +00:00 committed by Alexandre Julliard
parent a95e3e2923
commit cec8b6b014
1 changed files with 119 additions and 19 deletions

View File

@ -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",