From a5d28014763e5317d635aa3125c179b0aa9b2981 Mon Sep 17 00:00:00 2001 From: Reece Dunn Date: Thu, 10 Jul 2008 19:29:32 +0100 Subject: [PATCH] comctl32: Add support for drawing themed group boxes. --- dlls/comctl32/Makefile.in | 1 + dlls/comctl32/theme_button.c | 145 +++++++++++++++++++++++++++++++++++++++++++ dlls/comctl32/theming.c | 7 ++- 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 dlls/comctl32/theme_button.c diff --git a/dlls/comctl32/Makefile.in b/dlls/comctl32/Makefile.in index bf62a223151..ad96a505f51 100644 --- a/dlls/comctl32/Makefile.in +++ b/dlls/comctl32/Makefile.in @@ -34,6 +34,7 @@ C_SRCS = \ string.c \ syslink.c \ tab.c \ + theme_button.c \ theme_combo.c \ theme_dialog.c \ theme_edit.c \ diff --git a/dlls/comctl32/theme_button.c b/dlls/comctl32/theme_button.c new file mode 100644 index 00000000000..588f1a42a33 --- /dev/null +++ b/dlls/comctl32/theme_button.c @@ -0,0 +1,145 @@ +/* + * 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 +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "uxtheme.h" +#include "tmschema.h" +#include "comctl32.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(themingbutton); + +#define BUTTON_TYPE 0x0f /* bit mask for the available button types */ + +static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC) +{ + RECT bgRect, textRect; + SIZE textExtent; + HFONT font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); + HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL; + int state = IsWindowEnabled(hwnd) ? GBS_NORMAL : GBS_DISABLED; + WCHAR text[MAX_PATH]; + int len = MAX_PATH; + + GetClientRect(hwnd, &bgRect); + textRect = bgRect; + + len = GetWindowTextW(hwnd, text, len); + + GetTextExtentPoint32W(hDC, text, len, &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); + + DrawThemeBackground(theme, hDC, BP_GROUPBOX, state, &bgRect, NULL); + + SelectClipRgn(hDC, NULL); + + textRect.left += 2; + textRect.right -= 2; + DrawThemeText(theme, hDC, BP_GROUPBOX, state, text, len, 0, 0, &textRect); + + if (hPrevFont) SelectObject(hDC, hPrevFont); +} + +static BOOL BUTTON_Paint(HTHEME theme, HWND hwnd, HDC hParamDC) +{ + PAINTSTRUCT ps; + HDC hDC; + DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE); + + if ((dwStyle & BUTTON_TYPE) == BS_GROUPBOX) + { + hDC = hParamDC ? hParamDC : BeginPaint(hwnd, &ps); + GB_draw(theme, hwnd, hDC); + if (!hParamDC) EndPaint(hwnd, &ps); + } + else return FALSE; /* Delegate drawing to the non-themed code. */ + + 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 THEMING_CallOriginalClass(hwnd, msg, wParam, lParam); + + 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 5b5f6b304ee..090fe27ab51 100644 --- a/dlls/comctl32/theming.c +++ b/dlls/comctl32/theming.c @@ -34,6 +34,8 @@ 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); extern LRESULT CALLBACK THEMING_ComboSubclassProc (HWND, UINT, WPARAM, LPARAM, ULONG_PTR); extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM, @@ -53,6 +55,7 @@ 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_EDITW, THEMING_EditSubclassProc}, @@ -91,13 +94,15 @@ 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, subclass_proc1, subclass_proc2, subclass_proc3, - subclass_proc4 + subclass_proc4, + subclass_proc5 }; /*********************************************************************** -- 2.11.4.GIT