Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/Makefile.in | 1 - dlls/comctl32/button.c | 400 ++++++++++++++++++++++++++++++++++------ dlls/comctl32/theme_button.c | 423 ------------------------------------------- dlls/comctl32/theming.c | 7 - 4 files changed, 348 insertions(+), 483 deletions(-) delete mode 100644 dlls/comctl32/theme_button.c
diff --git a/dlls/comctl32/Makefile.in b/dlls/comctl32/Makefile.in index 1531dc4aed..03dd808427 100644 --- a/dlls/comctl32/Makefile.in +++ b/dlls/comctl32/Makefile.in @@ -34,7 +34,6 @@ C_SRCS = \ syslink.c \ tab.c \ taskdialog.c \ - theme_button.c \ theme_combo.c \ theme_dialog.c \ theme_listbox.c \ diff --git a/dlls/comctl32/button.c b/dlls/comctl32/button.c index 47fdd041da..c8f85d981e 100644 --- a/dlls/comctl32/button.c +++ b/dlls/comctl32/button.c @@ -2,6 +2,7 @@ * Copyright (C) 1993 Johannes Ruscheinski * Copyright (C) 1993 David Metcalfe * Copyright (C) 1994 Alexandre Julliard + * Copyright (C) 2008 by Reece H. Dunn * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -62,6 +63,9 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winuser.h" +#include "uxtheme.h" +#include "vssym32.h" #include "wine/debug.h"
#include "comctl32.h" @@ -118,6 +122,16 @@ static const WORD maxCheckState[MAX_BTN_TYPE] = BST_UNCHECKED /* BS_DEFCOMMANDLINK */ };
+/* These are indices into a states array to determine the theme state for a given theme part. */ +typedef enum +{ + STATE_NORMAL, + STATE_DISABLED, + STATE_HOT, + STATE_PRESSED, + STATE_DEFAULTED +} ButtonState; + typedef void (*pfPaint)( HWND hwnd, HDC hdc, UINT action );
static const pfPaint btnPaintFunc[MAX_BTN_TYPE] = @@ -140,6 +154,32 @@ static const pfPaint btnPaintFunc[MAX_BTN_TYPE] = PB_Paint /* BS_DEFCOMMANDLINK */ };
+typedef void (*pfThemedPaint)( HTHEME theme, HWND hwnd, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); + +static void PB_ThemedPaint( HTHEME theme, HWND hwnd, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); +static void CB_ThemedPaint( HTHEME theme, HWND hwnd, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); +static void GB_ThemedPaint( HTHEME theme, HWND hwnd, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); + +static const pfThemedPaint btnThemedPaintFunc[MAX_BTN_TYPE] = +{ + PB_ThemedPaint, /* BS_PUSHBUTTON */ + PB_ThemedPaint, /* BS_DEFPUSHBUTTON */ + CB_ThemedPaint, /* BS_CHECKBOX */ + CB_ThemedPaint, /* BS_AUTOCHECKBOX */ + CB_ThemedPaint, /* BS_RADIOBUTTON */ + CB_ThemedPaint, /* BS_3STATE */ + CB_ThemedPaint, /* BS_AUTO3STATE */ + GB_ThemedPaint, /* BS_GROUPBOX */ + NULL, /* BS_USERBUTTON */ + CB_ThemedPaint, /* BS_AUTORADIOBUTTON */ + NULL, /* BS_PUSHBOX */ + NULL, /* BS_OWNERDRAW */ + NULL, /* BS_SPLITBUTTON */ + NULL, /* BS_DEFSPLITBUTTON */ + NULL, /* BS_COMMANDLINK */ + NULL, /* BS_DEFCOMMANDLINK */ +}; + /********************************************************************* * button class descriptor */ @@ -209,6 +249,56 @@ HRGN set_control_clipping( HDC hdc, const RECT *rect ) return hrgn; }
+/********************************************************************** + * Convert button styles to flags used by DrawText. + */ +static UINT BUTTON_BStoDT( DWORD style, DWORD ex_style ) +{ + UINT dtStyle = DT_NOCLIP; /* We use SelectClipRgn to limit output */ + + /* "Convert" pushlike buttons to pushbuttons */ + if (style & BS_PUSHLIKE) + style &= ~BS_TYPEMASK; + + if (!(style & BS_MULTILINE)) + dtStyle |= DT_SINGLELINE; + else + dtStyle |= DT_WORDBREAK; + + switch (style & BS_CENTER) + { + case BS_LEFT: /* DT_LEFT is 0 */ break; + case BS_RIGHT: dtStyle |= DT_RIGHT; break; + case BS_CENTER: dtStyle |= DT_CENTER; break; + default: + /* Pushbutton's text is centered by default */ + if (get_button_type(style) <= BS_DEFPUSHBUTTON) dtStyle |= DT_CENTER; + /* all other flavours have left aligned text */ + } + + if (ex_style & WS_EX_RIGHT) dtStyle = DT_RIGHT | (dtStyle & ~(DT_LEFT | DT_CENTER)); + + /* DrawText ignores vertical alignment for multiline text, + * but we use these flags to align label manually. + */ + if (get_button_type(style) != BS_GROUPBOX) + { + switch (style & BS_VCENTER) + { + case BS_TOP: /* DT_TOP is 0 */ break; + case BS_BOTTOM: dtStyle |= DT_BOTTOM; break; + case BS_VCENTER: /* fall through */ + default: dtStyle |= DT_VCENTER; break; + } + } + else + /* GroupBox's text is always single line and is top aligned. */ + dtStyle |= DT_SINGLELINE; + + return dtStyle; +} + + static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { RECT rect; @@ -217,6 +307,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L UINT btn_type = get_button_type( style ); LONG state; HANDLE oldHbitmap; + HTHEME theme;
if (!IsWindow( hWnd )) return 0;
@@ -242,7 +333,11 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L }
case WM_ENABLE: - paint_button( hWnd, btn_type, ODA_DRAWENTIRE ); + theme = GetWindowTheme( hWnd ); + if (theme) + RedrawWindow( hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW ); + else + paint_button( hWnd, btn_type, ODA_DRAWENTIRE ); break;
case WM_CREATE: @@ -256,8 +351,20 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L SetWindowLongW( hWnd, GWL_STYLE, style ); } set_button_state( hWnd, BST_UNCHECKED ); + OpenThemeData( hWnd, WC_BUTTONW ); return 0;
+ case WM_DESTROY: + theme = GetWindowTheme( hWnd ); + CloseThemeData( theme ); + break; + + case WM_THEMECHANGED: + theme = GetWindowTheme( hWnd ); + CloseThemeData( theme ); + OpenThemeData( hWnd, WC_BUTTONW ); + break; + case WM_ERASEBKGND: if (btn_type == BS_OWNERDRAW) { @@ -279,13 +386,37 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L case WM_PAINT: { PAINTSTRUCT ps; - HDC hdc = wParam ? (HDC)wParam : BeginPaint( hWnd, &ps ); - if (btnPaintFunc[btn_type]) + HDC hdc; + + theme = GetWindowTheme( hWnd ); + hdc = wParam ? (HDC)wParam : BeginPaint( hWnd, &ps ); + + if (theme && btnPaintFunc[btn_type]) + { + ButtonState drawState; + UINT dtflags; + + state = get_button_state( hWnd ); + if (IsWindowEnabled( hWnd )) + { + if (state & BST_PUSHED) drawState = STATE_PRESSED; + else if (state & BST_HOT) drawState = STATE_HOT; + else if (state & BST_FOCUS) drawState = STATE_DEFAULTED; + else drawState = STATE_NORMAL; + } + else + drawState = STATE_DISABLED; + + dtflags = BUTTON_BStoDT(style, GetWindowLongW(hWnd, GWL_EXSTYLE)); + btnThemedPaintFunc[btn_type](theme, hWnd, hdc, drawState, dtflags, state & BST_FOCUS); + } + else if (btnPaintFunc[btn_type]) { int nOldMode = SetBkMode( hdc, OPAQUE ); (btnPaintFunc[btn_type])( hWnd, hdc, ODA_DRAWENTIRE ); SetBkMode(hdc, nOldMode); /* reset painting mode */ } + if ( !wParam ) EndPaint( hWnd, &ps ); break; } @@ -370,12 +501,40 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L break;
case WM_MOUSEMOVE: + { + TRACKMOUSEEVENT mouse_event; + + mouse_event.cbSize = sizeof(TRACKMOUSEEVENT); + mouse_event.dwFlags = TME_QUERY; + if (!TrackMouseEvent(&mouse_event) || !(mouse_event.dwFlags & (TME_HOVER | TME_LEAVE))) + { + mouse_event.dwFlags = TME_HOVER | TME_LEAVE; + mouse_event.hwndTrack = hWnd; + mouse_event.dwHoverTime = 1; + TrackMouseEvent(&mouse_event); + } + if ((wParam & MK_LBUTTON) && GetCapture() == hWnd) { GetClientRect( hWnd, &rect ); SendMessageW( hWnd, BM_SETSTATE, PtInRect(&rect, pt), 0 ); } break; + } + + case WM_MOUSEHOVER: + { + set_button_state( hWnd, get_button_state( hWnd ) | BST_HOT ); + InvalidateRect( hWnd, NULL, FALSE ); + break; + } + + case WM_MOUSELEAVE: + { + set_button_state( hWnd, get_button_state( hWnd ) & ~BST_HOT ); + InvalidateRect( hWnd, NULL, FALSE ); + break; + }
case WM_SETTEXT: { @@ -532,55 +691,6 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L return 0; }
-/********************************************************************** - * Convert button styles to flags used by DrawText. - */ -static UINT BUTTON_BStoDT( DWORD style, DWORD ex_style ) -{ - UINT dtStyle = DT_NOCLIP; /* We use SelectClipRgn to limit output */ - - /* "Convert" pushlike buttons to pushbuttons */ - if (style & BS_PUSHLIKE) - style &= ~BS_TYPEMASK; - - if (!(style & BS_MULTILINE)) - dtStyle |= DT_SINGLELINE; - else - dtStyle |= DT_WORDBREAK; - - switch (style & BS_CENTER) - { - case BS_LEFT: /* DT_LEFT is 0 */ break; - case BS_RIGHT: dtStyle |= DT_RIGHT; break; - case BS_CENTER: dtStyle |= DT_CENTER; break; - default: - /* Pushbutton's text is centered by default */ - if (get_button_type(style) <= BS_DEFPUSHBUTTON) dtStyle |= DT_CENTER; - /* all other flavours have left aligned text */ - } - - if (ex_style & WS_EX_RIGHT) dtStyle = DT_RIGHT | (dtStyle & ~(DT_LEFT | DT_CENTER)); - - /* DrawText ignores vertical alignment for multiline text, - * but we use these flags to align label manually. - */ - if (get_button_type(style) != BS_GROUPBOX) - { - switch (style & BS_VCENTER) - { - case BS_TOP: /* DT_TOP is 0 */ break; - case BS_BOTTOM: dtStyle |= DT_BOTTOM; break; - case BS_VCENTER: /* fall through */ - default: dtStyle |= DT_VCENTER; break; - } - } - else - /* GroupBox's text is always single line and is top aligned. */ - dtStyle |= DT_SINGLELINE; - - return dtStyle; -} - /********************************************************************** * BUTTON_CalcLabelRect * @@ -1140,6 +1250,192 @@ static void OB_Paint( HWND hwnd, HDC hDC, UINT action ) if (hrgn) DeleteObject( hrgn ); }
+static void PB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) +{ + static const int states[] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED, PBS_DEFAULTED }; + + RECT bgRect, textRect; + HFONT font = get_button_font( hwnd ); + HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL; + int state = states[ drawState ]; + WCHAR *text = get_button_text(hwnd); + + GetClientRect(hwnd, &bgRect); + GetThemeBackgroundContentRect(theme, hDC, BP_PUSHBUTTON, state, &bgRect, &textRect); + + if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state)) + DrawThemeParentBackground(hwnd, hDC, NULL); + DrawThemeBackground(theme, hDC, BP_PUSHBUTTON, state, &bgRect, NULL); + if (text) + { + DrawThemeText(theme, hDC, BP_PUSHBUTTON, state, text, lstrlenW(text), dtFlags, 0, &textRect); + HeapFree(GetProcessHeap(), 0, text); + } + + if (focused) + { + MARGINS margins; + RECT focusRect = bgRect; + + GetThemeMargins(theme, hDC, BP_PUSHBUTTON, state, TMT_CONTENTMARGINS, NULL, &margins); + + focusRect.left += margins.cxLeftWidth; + focusRect.top += margins.cyTopHeight; + focusRect.right -= margins.cxRightWidth; + focusRect.bottom -= margins.cyBottomHeight; + + DrawFocusRect( hDC, &focusRect ); + } + + if (hPrevFont) SelectObject(hDC, hPrevFont); +} + +static void CB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) +{ + static const int cb_states[3][5] = + { + { CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDNORMAL }, + { CBS_CHECKEDNORMAL, CBS_CHECKEDDISABLED, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDNORMAL }, + { CBS_MIXEDNORMAL, CBS_MIXEDDISABLED, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDNORMAL } + }; + + static const int rb_states[2][5] = + { + { RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDNORMAL }, + { RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL } + }; + + SIZE sz; + RECT bgRect, textRect; + HFONT font, hPrevFont = NULL; + int checkState = get_button_state( hwnd ) & 3; + DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE); + UINT btn_type = get_button_type( dwStyle ); + int part = (btn_type == BS_RADIOBUTTON) || (btn_type == BS_AUTORADIOBUTTON) ? BP_RADIOBUTTON : BP_CHECKBOX; + int state = (part == BP_CHECKBOX) + ? cb_states[ checkState ][ drawState ] + : rb_states[ checkState ][ drawState ]; + WCHAR *text = get_button_text(hwnd); + LOGFONTW lf; + BOOL created_font = FALSE; + + HRESULT hr = GetThemeFont(theme, hDC, part, state, TMT_FONT, &lf); + if (SUCCEEDED(hr)) { + font = CreateFontIndirectW(&lf); + if (!font) + TRACE("Failed to create font\n"); + else { + TRACE("font = %s\n", debugstr_w(lf.lfFaceName)); + hPrevFont = SelectObject(hDC, font); + created_font = TRUE; + } + } else { + font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); + hPrevFont = SelectObject(hDC, font); + } + + if (FAILED(GetThemePartSize(theme, hDC, part, state, NULL, TS_DRAW, &sz))) + sz.cx = sz.cy = 13; + + GetClientRect(hwnd, &bgRect); + GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect); + + if (dtFlags & DT_SINGLELINE) /* Center the checkbox / radio button to the text. */ + bgRect.top = bgRect.top + (textRect.bottom - textRect.top - sz.cy) / 2; + + /* adjust for the check/radio marker */ + bgRect.bottom = bgRect.top + sz.cy; + bgRect.right = bgRect.left + sz.cx; + textRect.left = bgRect.right + 6; + + DrawThemeParentBackground(hwnd, hDC, NULL); + + DrawThemeBackground(theme, hDC, part, state, &bgRect, NULL); + if (text) + { + DrawThemeText(theme, hDC, part, state, text, lstrlenW(text), dtFlags, 0, &textRect); + + if (focused) + { + RECT focusRect; + + focusRect = textRect; + + DrawTextW(hDC, text, lstrlenW(text), &focusRect, dtFlags | DT_CALCRECT); + + if (focusRect.right < textRect.right) focusRect.right++; + focusRect.bottom = textRect.bottom; + + DrawFocusRect( hDC, &focusRect ); + } + + HeapFree(GetProcessHeap(), 0, text); + } + + if (created_font) DeleteObject(font); + if (hPrevFont) SelectObject(hDC, hPrevFont); +} + +static void GB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) +{ + static const int states[] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL, GBS_NORMAL }; + + RECT bgRect, textRect, contentRect; + int state = states[ drawState ]; + WCHAR *text = get_button_text(hwnd); + LOGFONTW lf; + HFONT font, hPrevFont = NULL; + BOOL created_font = FALSE; + + HRESULT hr = GetThemeFont(theme, hDC, BP_GROUPBOX, state, TMT_FONT, &lf); + if (SUCCEEDED(hr)) { + font = CreateFontIndirectW(&lf); + if (!font) + TRACE("Failed to create font\n"); + else { + hPrevFont = SelectObject(hDC, font); + created_font = TRUE; + } + } else { + font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); + hPrevFont = SelectObject(hDC, font); + } + + GetClientRect(hwnd, &bgRect); + textRect = bgRect; + + if (text) + { + SIZE textExtent; + GetTextExtentPoint32W(hDC, text, lstrlenW(text), &textExtent); + bgRect.top += (textExtent.cy / 2); + textRect.left += 10; + textRect.bottom = textRect.top + textExtent.cy; + textRect.right = textRect.left + textExtent.cx + 4; + + ExcludeClipRect(hDC, textRect.left, textRect.top, textRect.right, textRect.bottom); + } + + GetThemeBackgroundContentRect(theme, hDC, BP_GROUPBOX, state, &bgRect, &contentRect); + ExcludeClipRect(hDC, contentRect.left, contentRect.top, contentRect.right, contentRect.bottom); + + if (IsThemeBackgroundPartiallyTransparent(theme, BP_GROUPBOX, state)) + DrawThemeParentBackground(hwnd, hDC, NULL); + DrawThemeBackground(theme, hDC, BP_GROUPBOX, state, &bgRect, NULL); + + SelectClipRgn(hDC, NULL); + + if (text) + { + InflateRect(&textRect, -2, 0); + DrawThemeText(theme, hDC, BP_GROUPBOX, state, text, lstrlenW(text), 0, 0, &textRect); + HeapFree(GetProcessHeap(), 0, text); + } + + if (created_font) DeleteObject(font); + if (hPrevFont) SelectObject(hDC, hPrevFont); +} + void BUTTON_Register(void) { WNDCLASSW wndClass; diff --git a/dlls/comctl32/theme_button.c b/dlls/comctl32/theme_button.c deleted file mode 100644 index f136b5df33..0000000000 --- a/dlls/comctl32/theme_button.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Theming - Button control - * - * Copyright (c) 2008 by Reece H. Dunn - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#include <stdarg.h> -#include <string.h> -#include <stdlib.h> - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "uxtheme.h" -#include "vssym32.h" -#include "comctl32.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(theme_button); - -#define BUTTON_TYPE 0x0f /* bit mask for the available button types */ - -/* These are indices into a states array to determine the theme state for a given theme part. */ -typedef enum -{ - STATE_NORMAL, - STATE_DISABLED, - STATE_HOT, - STATE_PRESSED, - STATE_DEFAULTED -} ButtonState; - -typedef void (*pfThemedPaint)(HTHEME theme, HWND hwnd, HDC hdc, ButtonState drawState, UINT dtFlags, BOOL focused); - -static UINT get_drawtext_flags(DWORD style, DWORD ex_style) -{ - UINT flags = 0; - - if (style & BS_PUSHLIKE) - style &= ~BUTTON_TYPE; - - if (!(style & BS_MULTILINE)) - flags |= DT_SINGLELINE; - else - flags |= DT_WORDBREAK; - - switch (style & BS_CENTER) - { - case BS_LEFT: flags |= DT_LEFT; break; - case BS_RIGHT: flags |= DT_RIGHT; break; - case BS_CENTER: flags |= DT_CENTER; break; - default: - flags |= ((style & BUTTON_TYPE) <= BS_DEFPUSHBUTTON) - ? DT_CENTER : DT_LEFT; - } - - if (ex_style & WS_EX_RIGHT) - flags = DT_RIGHT | (flags & ~(DT_LEFT | DT_CENTER)); - - if ((style & BUTTON_TYPE) != BS_GROUPBOX) - { - switch (style & BS_VCENTER) - { - case BS_TOP: flags |= DT_TOP; break; - case BS_BOTTOM: flags |= DT_BOTTOM; break; - case BS_VCENTER: /* fall through */ - default: flags |= DT_VCENTER; break; - } - } - else - /* GroupBox's text is always single line and is top aligned. */ - flags |= DT_SINGLELINE | DT_TOP; - - return flags; -} - -static inline WCHAR *get_button_text(HWND hwnd) -{ - INT len = 512; - WCHAR *text; - text = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); - if (text) InternalGetWindowText(hwnd, text, len + 1); - return text; -} - -static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) -{ - static const int states[] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED, PBS_DEFAULTED }; - - RECT bgRect, textRect; - HFONT font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); - HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL; - int state = states[ drawState ]; - WCHAR *text = get_button_text(hwnd); - - GetClientRect(hwnd, &bgRect); - GetThemeBackgroundContentRect(theme, hDC, BP_PUSHBUTTON, state, &bgRect, &textRect); - - if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state)) - DrawThemeParentBackground(hwnd, hDC, NULL); - DrawThemeBackground(theme, hDC, BP_PUSHBUTTON, state, &bgRect, NULL); - if (text) - { - DrawThemeText(theme, hDC, BP_PUSHBUTTON, state, text, lstrlenW(text), dtFlags, 0, &textRect); - HeapFree(GetProcessHeap(), 0, text); - } - - if (focused) - { - MARGINS margins; - RECT focusRect = bgRect; - - GetThemeMargins(theme, hDC, BP_PUSHBUTTON, state, TMT_CONTENTMARGINS, NULL, &margins); - - focusRect.left += margins.cxLeftWidth; - focusRect.top += margins.cyTopHeight; - focusRect.right -= margins.cxRightWidth; - focusRect.bottom -= margins.cyBottomHeight; - - DrawFocusRect( hDC, &focusRect ); - } - - if (hPrevFont) SelectObject(hDC, hPrevFont); -} - -static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) -{ - static const int cb_states[3][5] = - { - { CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDNORMAL }, - { CBS_CHECKEDNORMAL, CBS_CHECKEDDISABLED, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDNORMAL }, - { CBS_MIXEDNORMAL, CBS_MIXEDDISABLED, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDNORMAL } - }; - - static const int rb_states[2][5] = - { - { RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDNORMAL }, - { RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL } - }; - - SIZE sz; - RECT bgRect, textRect; - HFONT font, hPrevFont = NULL; - LRESULT checkState = SendMessageW(hwnd, BM_GETCHECK, 0, 0); - DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE); - int part = ((dwStyle & BUTTON_TYPE) == BS_RADIOBUTTON) || ((dwStyle & BUTTON_TYPE) == BS_AUTORADIOBUTTON) - ? BP_RADIOBUTTON - : BP_CHECKBOX; - int state = (part == BP_CHECKBOX) - ? cb_states[ checkState ][ drawState ] - : rb_states[ checkState ][ drawState ]; - WCHAR *text = get_button_text(hwnd); - LOGFONTW lf; - BOOL created_font = FALSE; - - HRESULT hr = GetThemeFont(theme, hDC, part, state, TMT_FONT, &lf); - if (SUCCEEDED(hr)) { - font = CreateFontIndirectW(&lf); - if (!font) - TRACE("Failed to create font\n"); - else { - TRACE("font = %s\n", debugstr_w(lf.lfFaceName)); - hPrevFont = SelectObject(hDC, font); - created_font = TRUE; - } - } else { - font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); - hPrevFont = SelectObject(hDC, font); - } - - if (FAILED(GetThemePartSize(theme, hDC, part, state, NULL, TS_DRAW, &sz))) - sz.cx = sz.cy = 13; - - GetClientRect(hwnd, &bgRect); - GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect); - - if (dtFlags & DT_SINGLELINE) /* Center the checkbox / radio button to the text. */ - bgRect.top = bgRect.top + (textRect.bottom - textRect.top - sz.cy) / 2; - - /* adjust for the check/radio marker */ - bgRect.bottom = bgRect.top + sz.cy; - bgRect.right = bgRect.left + sz.cx; - textRect.left = bgRect.right + 6; - - DrawThemeParentBackground(hwnd, hDC, NULL); - - DrawThemeBackground(theme, hDC, part, state, &bgRect, NULL); - if (text) - { - DrawThemeText(theme, hDC, part, state, text, lstrlenW(text), dtFlags, 0, &textRect); - - if (focused) - { - RECT focusRect; - - focusRect = textRect; - - DrawTextW(hDC, text, lstrlenW(text), &focusRect, dtFlags | DT_CALCRECT); - - if (focusRect.right < textRect.right) focusRect.right++; - focusRect.bottom = textRect.bottom; - - DrawFocusRect( hDC, &focusRect ); - } - - HeapFree(GetProcessHeap(), 0, text); - } - - if (created_font) DeleteObject(font); - if (hPrevFont) SelectObject(hDC, hPrevFont); -} - -static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) -{ - static const int states[] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL, GBS_NORMAL }; - - RECT bgRect, textRect, contentRect; - int state = states[ drawState ]; - WCHAR *text = get_button_text(hwnd); - LOGFONTW lf; - HFONT font, hPrevFont = NULL; - BOOL created_font = FALSE; - - HRESULT hr = GetThemeFont(theme, hDC, BP_GROUPBOX, state, TMT_FONT, &lf); - if (SUCCEEDED(hr)) { - font = CreateFontIndirectW(&lf); - if (!font) - TRACE("Failed to create font\n"); - else { - hPrevFont = SelectObject(hDC, font); - created_font = TRUE; - } - } else { - font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); - hPrevFont = SelectObject(hDC, font); - } - - GetClientRect(hwnd, &bgRect); - textRect = bgRect; - - if (text) - { - SIZE textExtent; - GetTextExtentPoint32W(hDC, text, lstrlenW(text), &textExtent); - bgRect.top += (textExtent.cy / 2); - textRect.left += 10; - textRect.bottom = textRect.top + textExtent.cy; - textRect.right = textRect.left + textExtent.cx + 4; - - ExcludeClipRect(hDC, textRect.left, textRect.top, textRect.right, textRect.bottom); - } - - GetThemeBackgroundContentRect(theme, hDC, BP_GROUPBOX, state, &bgRect, &contentRect); - ExcludeClipRect(hDC, contentRect.left, contentRect.top, contentRect.right, contentRect.bottom); - - if (IsThemeBackgroundPartiallyTransparent(theme, BP_GROUPBOX, state)) - DrawThemeParentBackground(hwnd, hDC, NULL); - DrawThemeBackground(theme, hDC, BP_GROUPBOX, state, &bgRect, NULL); - - SelectClipRgn(hDC, NULL); - - if (text) - { - InflateRect(&textRect, -2, 0); - DrawThemeText(theme, hDC, BP_GROUPBOX, state, text, lstrlenW(text), 0, 0, &textRect); - HeapFree(GetProcessHeap(), 0, text); - } - - if (created_font) DeleteObject(font); - if (hPrevFont) SelectObject(hDC, hPrevFont); -} - -static const pfThemedPaint btnThemedPaintFunc[BUTTON_TYPE + 1] = -{ - PB_draw, /* BS_PUSHBUTTON */ - PB_draw, /* BS_DEFPUSHBUTTON */ - CB_draw, /* BS_CHECKBOX */ - CB_draw, /* BS_AUTOCHECKBOX */ - CB_draw, /* BS_RADIOBUTTON */ - CB_draw, /* BS_3STATE */ - CB_draw, /* BS_AUTO3STATE */ - GB_draw, /* BS_GROUPBOX */ - NULL, /* BS_USERBUTTON */ - CB_draw, /* BS_AUTORADIOBUTTON */ - NULL, /* Not defined */ - NULL, /* BS_OWNERDRAW */ - NULL, /* Not defined */ - NULL, /* Not defined */ - NULL, /* Not defined */ - NULL, /* Not defined */ -}; - -static BOOL BUTTON_Paint(HTHEME theme, HWND hwnd, HDC hParamDC) -{ - PAINTSTRUCT ps; - HDC hDC; - DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE); - DWORD dwStyleEx = GetWindowLongW(hwnd, GWL_EXSTYLE); - UINT dtFlags = get_drawtext_flags(dwStyle, dwStyleEx); - int state = (int)SendMessageW(hwnd, BM_GETSTATE, 0, 0); - ButtonState drawState; - pfThemedPaint paint = btnThemedPaintFunc[ dwStyle & BUTTON_TYPE ]; - - if(IsWindowEnabled(hwnd)) - { - if(state & BST_PUSHED) drawState = STATE_PRESSED; - else if(state & BST_HOT) drawState = STATE_HOT; - else if(state & BST_FOCUS) drawState = STATE_DEFAULTED; - else drawState = STATE_NORMAL; - } - else drawState = STATE_DISABLED; - - hDC = hParamDC ? hParamDC : BeginPaint(hwnd, &ps); - if (paint) paint(theme, hwnd, hDC, drawState, dtFlags, state & BST_FOCUS); - if (!hParamDC) EndPaint(hwnd, &ps); - return TRUE; -} - -/********************************************************************** - * The button control subclass window proc. - */ -LRESULT CALLBACK THEMING_ButtonSubclassProc(HWND hwnd, UINT msg, - WPARAM wParam, LPARAM lParam, - ULONG_PTR dwRefData) -{ - const WCHAR* themeClass = WC_BUTTONW; - HTHEME theme; - LRESULT result; - - switch (msg) - { - case WM_CREATE: - result = THEMING_CallOriginalClass(hwnd, msg, wParam, lParam); - OpenThemeData(hwnd, themeClass); - return result; - - case WM_DESTROY: - theme = GetWindowTheme(hwnd); - CloseThemeData (theme); - return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam); - - case WM_THEMECHANGED: - theme = GetWindowTheme(hwnd); - CloseThemeData (theme); - OpenThemeData(hwnd, themeClass); - break; - - case WM_SYSCOLORCHANGE: - theme = GetWindowTheme(hwnd); - if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam); - /* Do nothing. When themed, a WM_THEMECHANGED will be received, too, - * which will do the repaint. */ - break; - - case WM_PAINT: - theme = GetWindowTheme(hwnd); - if (theme && BUTTON_Paint(theme, hwnd, (HDC)wParam)) - return 0; - else - return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam); - - case WM_ENABLE: - theme = GetWindowTheme(hwnd); - if (theme) { - RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); - return 0; - } else - return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam); - - case WM_MOUSEMOVE: - { - TRACKMOUSEEVENT mouse_event; - mouse_event.cbSize = sizeof(TRACKMOUSEEVENT); - mouse_event.dwFlags = TME_QUERY; - if(!TrackMouseEvent(&mouse_event) || !(mouse_event.dwFlags&(TME_HOVER|TME_LEAVE))) - { - mouse_event.dwFlags = TME_HOVER|TME_LEAVE; - mouse_event.hwndTrack = hwnd; - mouse_event.dwHoverTime = 1; - TrackMouseEvent(&mouse_event); - } - break; - } - - case WM_MOUSEHOVER: - { - int state = (int)SendMessageW(hwnd, BM_GETSTATE, 0, 0); - SetWindowLongW(hwnd, 0, state|BST_HOT); - InvalidateRect(hwnd, NULL, FALSE); - break; - } - - case WM_MOUSELEAVE: - { - int state = (int)SendMessageW(hwnd, BM_GETSTATE, 0, 0); - SetWindowLongW(hwnd, 0, state&(~BST_HOT)); - InvalidateRect(hwnd, NULL, FALSE); - break; - } - - default: - /* Call old proc */ - return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam); - } - return 0; -} diff --git a/dlls/comctl32/theming.c b/dlls/comctl32/theming.c index 0f722fddce..06bdf81d41 100644 --- a/dlls/comctl32/theming.c +++ b/dlls/comctl32/theming.c @@ -34,14 +34,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(theming); typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM, ULONG_PTR);
-extern LRESULT CALLBACK THEMING_ButtonSubclassProc (HWND, UINT, WPARAM, LPARAM, - ULONG_PTR) DECLSPEC_HIDDEN; extern LRESULT CALLBACK THEMING_ComboSubclassProc (HWND, UINT, WPARAM, LPARAM, ULONG_PTR) DECLSPEC_HIDDEN; extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM, ULONG_PTR) DECLSPEC_HIDDEN; -extern LRESULT CALLBACK THEMING_EditSubclassProc (HWND, UINT, WPARAM, LPARAM, - ULONG_PTR) DECLSPEC_HIDDEN; extern LRESULT CALLBACK THEMING_ListBoxSubclassProc (HWND, UINT, WPARAM, LPARAM, ULONG_PTR) DECLSPEC_HIDDEN; extern LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND, UINT, WPARAM, LPARAM, @@ -57,7 +53,6 @@ static const struct ThemingSubclass } subclasses[] = { /* Note: list must be sorted by class name */ {dialogClass, THEMING_DialogSubclassProc}, - {WC_BUTTONW, THEMING_ButtonSubclassProc}, {WC_COMBOBOXW, THEMING_ComboSubclassProc}, {comboLboxClass, THEMING_ListBoxSubclassProc}, {WC_LISTBOXW, THEMING_ListBoxSubclassProc}, @@ -96,7 +91,6 @@ MAKE_SUBCLASS_PROC(1) MAKE_SUBCLASS_PROC(2) MAKE_SUBCLASS_PROC(3) MAKE_SUBCLASS_PROC(4) -MAKE_SUBCLASS_PROC(5)
static const WNDPROC subclassProcs[NUM_SUBCLASSES] = { subclass_proc0, @@ -104,7 +98,6 @@ static const WNDPROC subclassProcs[NUM_SUBCLASSES] = { subclass_proc2, subclass_proc3, subclass_proc4, - subclass_proc5, };
/***********************************************************************
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/button.c | 22 +++++++++++++++------- dlls/comctl32/tests/button.c | 10 +++------- 2 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/dlls/comctl32/button.c b/dlls/comctl32/button.c index c8f85d981e..85aa47f4bb 100644 --- a/dlls/comctl32/button.c +++ b/dlls/comctl32/button.c @@ -305,7 +305,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L POINT pt; LONG style = GetWindowLongW( hWnd, GWL_STYLE ); UINT btn_type = get_button_type( style ); - LONG state; + LONG state, new_state; HANDLE oldHbitmap; HTHEME theme;
@@ -674,12 +674,21 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
case BM_SETSTATE: state = get_button_state( hWnd ); - if (wParam) - set_button_state( hWnd, state | BST_PUSHED ); - else - set_button_state( hWnd, state & ~BST_PUSHED ); + new_state = wParam ? BST_PUSHED : 0; + + if ((state ^ new_state) & BST_PUSHED) + { + if (wParam) + state |= BST_PUSHED; + else + state &= ~BST_PUSHED;
- paint_button( hWnd, btn_type, ODA_SELECT ); + if (btn_type == BS_USERBUTTON) + BUTTON_NOTIFY_PARENT( hWnd, (state & BST_PUSHED) ? BN_HILITE : BN_UNHILITE ); + set_button_state( hWnd, state ); + + InvalidateRect( hWnd, NULL, FALSE ); + } break;
case WM_NCHITTEST: @@ -1206,7 +1215,6 @@ static void UB_Paint( HWND hwnd, HDC hDC, UINT action ) break;
default: - BUTTON_NOTIFY_PARENT( hwnd, BN_PAINT ); break; } } diff --git a/dlls/comctl32/tests/button.c b/dlls/comctl32/tests/button.c index 425e1455ff..38446aab67 100644 --- a/dlls/comctl32/tests/button.c +++ b/dlls/comctl32/tests/button.c @@ -350,8 +350,6 @@ static const struct message setstate_seq[] = { BM_SETSTATE, sent }, { WM_APP, sent|wparam|lparam, 0, 0 }, { WM_PAINT, sent }, - { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */ - { WM_ERASEBKGND, sent|defwinproc|optional }, { WM_PAINT, sent|optional }, { 0 } }; @@ -372,8 +370,6 @@ static const struct message setstate_user_seq[] = { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_HILITE) }, { WM_APP, sent|wparam|lparam, 0, 0 }, { WM_PAINT, sent }, - { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */ - { WM_ERASEBKGND, sent|defwinproc|optional }, { 0 } };
@@ -596,7 +592,7 @@ static void test_button_messages(void) SendMessageA(hwnd, BM_SETSTYLE, button[i].style | BS_BOTTOM, TRUE); SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); - todo = button[i].style == BS_USERBUTTON || button[i].style == BS_OWNERDRAW; + todo = button[i].style == BS_OWNERDRAW; ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setstyle, "BM_SETSTYLE on a button", todo);
style = GetWindowLongA(hwnd, GWL_STYLE); @@ -612,7 +608,7 @@ static void test_button_messages(void) SendMessageA(hwnd, BM_SETSTATE, TRUE, 0); SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); - ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setstate, "BM_SETSTATE/TRUE on a button", TRUE); + ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setstate, "BM_SETSTATE/TRUE on a button", FALSE);
state = SendMessageA(hwnd, BM_GETSTATE, 0, 0); ok(state == BST_PUSHED, "expected state 0x0004, got %04x\n", state); @@ -626,7 +622,7 @@ static void test_button_messages(void) SendMessageA(hwnd, BM_SETSTATE, FALSE, 0); SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); - ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].clearstate, "BM_SETSTATE/FALSE on a button", TRUE); + ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].clearstate, "BM_SETSTATE/FALSE on a button", FALSE);
state = SendMessageA(hwnd, BM_GETSTATE, 0, 0); ok(state == 0, "expected state 0, got %04x\n", state);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/button.c | 2 +- dlls/comctl32/tests/button.c | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/dlls/comctl32/button.c b/dlls/comctl32/button.c index 85aa47f4bb..2f5a5b3f17 100644 --- a/dlls/comctl32/button.c +++ b/dlls/comctl32/button.c @@ -663,7 +663,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L if ((state & 3) != wParam) { set_button_state( hWnd, (state & ~3) | wParam ); - paint_button( hWnd, btn_type, ODA_SELECT ); + InvalidateRect( hWnd, NULL, FALSE ); } if ((btn_type == BS_AUTORADIOBUTTON) && (wParam == BST_CHECKED) && (style & WS_CHILD)) BUTTON_CheckAutoRadioButton( hWnd ); diff --git a/dlls/comctl32/tests/button.c b/dlls/comctl32/tests/button.c index 38446aab67..96b8bea531 100644 --- a/dlls/comctl32/tests/button.c +++ b/dlls/comctl32/tests/button.c @@ -440,8 +440,7 @@ static const struct message setcheck_radio_redraw_seq[] = { WM_STYLECHANGED, sent|wparam|defwinproc, GWL_STYLE }, { WM_APP, sent|wparam|lparam, 0, 0 }, { WM_PAINT, sent }, - { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */ - { WM_ERASEBKGND, sent|defwinproc|optional }, + { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */ { 0 } };
@@ -661,7 +660,9 @@ static void test_button_messages(void) SendMessageA(hwnd, BM_SETCHECK, BST_CHECKED, 0); SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setcheck, "BM_SETCHECK on a button", FALSE);
+ state = SendMessageA(hwnd, BM_GETCHECK, 0, 0); if (button[i].style == BS_PUSHBUTTON || button[i].style == BS_DEFPUSHBUTTON || button[i].style == BS_GROUPBOX || @@ -672,16 +673,10 @@ static void test_button_messages(void) button[i].style == BS_COMMANDLINK || button[i].style == BS_DEFCOMMANDLINK) { - ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setcheck, "BM_SETCHECK on a button", FALSE); - state = SendMessageA(hwnd, BM_GETCHECK, 0, 0); ok(state == BST_UNCHECKED, "expected check BST_UNCHECKED, got %04x\n", state); } else - { - ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setcheck, "BM_SETCHECK on a button", TRUE); - state = SendMessageA(hwnd, BM_GETCHECK, 0, 0); ok(state == BST_CHECKED, "expected check BST_CHECKED, got %04x\n", state); - }
style = GetWindowLongA(hwnd, GWL_STYLE); style &= ~(WS_CHILD | BS_NOTIFY | WS_VISIBLE);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/static.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-)
diff --git a/dlls/comctl32/static.c b/dlls/comctl32/static.c index 49127fa2c5..d9e2fe30dc 100644 --- a/dlls/comctl32/static.c +++ b/dlls/comctl32/static.c @@ -55,8 +55,6 @@ static void STATIC_PaintBitmapfn( HWND hwnd, HDC hdc, DWORD style ); static void STATIC_PaintEnhMetafn( HWND hwnd, HDC hdc, DWORD style ); static void STATIC_PaintEtchedfn( HWND hwnd, HDC hdc, DWORD style );
-static COLORREF color_3dshadow, color_3ddkshadow, color_3dhighlight; - /* offsets for GetWindowLong for static private information */ #define HFONT_GWL_OFFSET 0 #define HICON_GWL_OFFSET (sizeof(HFONT)) @@ -292,13 +290,6 @@ static HBRUSH STATIC_SendWmCtlColorStatic(HWND hwnd, HDC hdc) return hBrush; }
-static VOID STATIC_InitColours(void) -{ - color_3ddkshadow = GetSysColor(COLOR_3DDKSHADOW); - color_3dshadow = GetSysColor(COLOR_3DSHADOW); - color_3dhighlight = GetSysColor(COLOR_3DHIGHLIGHT); -} - /*********************************************************************** * hasTextStyle * @@ -336,7 +327,6 @@ static LRESULT CALLBACK STATIC_WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, ERR("Unknown style 0x%02x\n", style ); return -1; } - STATIC_InitColours(); break;
case WM_NCDESTROY: @@ -391,7 +381,7 @@ static LRESULT CALLBACK STATIC_WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, break;
case WM_SYSCOLORCHANGE: - STATIC_InitColours(); + COMCTL32_RefreshSysColors(); STATIC_TryPaintFcn( hwnd, full_style ); break;
@@ -644,27 +634,27 @@ static void STATIC_PaintRectfn( HWND hwnd, HDC hdc, DWORD style ) switch (style & SS_TYPEMASK) { case SS_BLACKRECT: - hBrush = CreateSolidBrush(color_3ddkshadow); + hBrush = CreateSolidBrush(comctl32_color.clr3dDkShadow); FillRect( hdc, &rc, hBrush ); break; case SS_GRAYRECT: - hBrush = CreateSolidBrush(color_3dshadow); + hBrush = CreateSolidBrush(comctl32_color.clr3dShadow); FillRect( hdc, &rc, hBrush ); break; case SS_WHITERECT: - hBrush = CreateSolidBrush(color_3dhighlight); + hBrush = CreateSolidBrush(comctl32_color.clr3dHilight); FillRect( hdc, &rc, hBrush ); break; case SS_BLACKFRAME: - hBrush = CreateSolidBrush(color_3ddkshadow); + hBrush = CreateSolidBrush(comctl32_color.clr3dDkShadow); FrameRect( hdc, &rc, hBrush ); break; case SS_GRAYFRAME: - hBrush = CreateSolidBrush(color_3dshadow); + hBrush = CreateSolidBrush(comctl32_color.clr3dShadow); FrameRect( hdc, &rc, hBrush ); break; case SS_WHITEFRAME: - hBrush = CreateSolidBrush(color_3dhighlight); + hBrush = CreateSolidBrush(comctl32_color.clr3dHilight); FrameRect( hdc, &rc, hBrush ); break; default: