2 * Theming - Button control
4 * Copyright (c) 2008 by Reece H. Dunn
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(themingbutton
);
37 #define BUTTON_TYPE 0x0f /* bit mask for the available button types */
39 typedef void (*pfThemedPaint
)(HTHEME theme
, HWND hwnd
, HDC hdc
);
41 static void GB_draw(HTHEME theme
, HWND hwnd
, HDC hDC
)
43 RECT bgRect
, textRect
;
45 HFONT font
= (HFONT
)SendMessageW(hwnd
, WM_GETFONT
, 0, 0);
46 HFONT hPrevFont
= font
? SelectObject(hDC
, font
) : NULL
;
47 int state
= IsWindowEnabled(hwnd
) ? GBS_NORMAL
: GBS_DISABLED
;
51 GetClientRect(hwnd
, &bgRect
);
54 len
= GetWindowTextW(hwnd
, text
, len
);
56 GetTextExtentPoint32W(hDC
, text
, len
, &textExtent
);
58 bgRect
.top
+= (textExtent
.cy
/ 2);
60 textRect
.bottom
= textRect
.top
+ textExtent
.cy
;
61 textRect
.right
= textRect
.left
+ textExtent
.cx
+ 4;
63 ExcludeClipRect(hDC
, textRect
.left
, textRect
.top
, textRect
.right
, textRect
.bottom
);
65 DrawThemeBackground(theme
, hDC
, BP_GROUPBOX
, state
, &bgRect
, NULL
);
67 SelectClipRgn(hDC
, NULL
);
71 DrawThemeText(theme
, hDC
, BP_GROUPBOX
, state
, text
, len
, 0, 0, &textRect
);
73 if (hPrevFont
) SelectObject(hDC
, hPrevFont
);
76 static const pfThemedPaint btnThemedPaintFunc
[BUTTON_TYPE
+ 1] =
78 NULL
, /* BS_PUSHBUTTON */
79 NULL
, /* BS_DEFPUSHBUTTON */
80 NULL
, /* BS_CHECKBOX */
81 NULL
, /* BS_AUTOCHECKBOX */
82 NULL
, /* BS_RADIOBUTTON */
84 NULL
, /* BS_AUTO3STATE */
85 GB_draw
, /* BS_GROUPBOX */
86 NULL
, /* BS_USERBUTTON */
87 NULL
, /* BS_AUTORADIOBUTTON */
88 NULL
, /* Not defined */
89 NULL
, /* BS_OWNERDRAW */
90 NULL
, /* Not defined */
91 NULL
, /* Not defined */
92 NULL
, /* Not defined */
93 NULL
, /* Not defined */
96 static BOOL
BUTTON_Paint(HTHEME theme
, HWND hwnd
, HDC hParamDC
)
100 DWORD dwStyle
= GetWindowLongW(hwnd
, GWL_STYLE
);
101 pfThemedPaint paint
= btnThemedPaintFunc
[ dwStyle
& BUTTON_TYPE
];
105 hDC
= hParamDC
? hParamDC
: BeginPaint(hwnd
, &ps
);
106 paint(theme
, hwnd
, hDC
);
107 if (!hParamDC
) EndPaint(hwnd
, &ps
);
111 return FALSE
; /* Delegate drawing to the non-themed code. */
114 /**********************************************************************
115 * The button control subclass window proc.
117 LRESULT CALLBACK
THEMING_ButtonSubclassProc(HWND hwnd
, UINT msg
,
118 WPARAM wParam
, LPARAM lParam
,
121 const WCHAR
* themeClass
= WC_BUTTONW
;
128 result
= THEMING_CallOriginalClass(hwnd
, msg
, wParam
, lParam
);
129 OpenThemeData(hwnd
, themeClass
);
133 theme
= GetWindowTheme(hwnd
);
134 CloseThemeData (theme
);
135 return THEMING_CallOriginalClass(hwnd
, msg
, wParam
, lParam
);
137 case WM_THEMECHANGED
:
138 theme
= GetWindowTheme(hwnd
);
139 CloseThemeData (theme
);
140 OpenThemeData(hwnd
, themeClass
);
143 case WM_SYSCOLORCHANGE
:
144 theme
= GetWindowTheme(hwnd
);
145 if (!theme
) return THEMING_CallOriginalClass(hwnd
, msg
, wParam
, lParam
);
146 /* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
147 * which will do the repaint. */
151 theme
= GetWindowTheme(hwnd
);
152 if (theme
&& BUTTON_Paint(theme
, hwnd
, (HDC
)wParam
))
155 return THEMING_CallOriginalClass(hwnd
, msg
, wParam
, lParam
);
158 theme
= GetWindowTheme(hwnd
);
159 if (theme
) RedrawWindow(hwnd
, NULL
, NULL
,
160 RDW_FRAME
| RDW_INVALIDATE
| RDW_UPDATENOW
);
161 return THEMING_CallOriginalClass(hwnd
, msg
, wParam
, lParam
);
165 return THEMING_CallOriginalClass(hwnd
, msg
, wParam
, lParam
);