https://git.reactos.org/?p=reactos.git;a=commitdiff;h=18dee7a39228f11ade4d9…
commit 18dee7a39228f11ade4d95d1e2715672c3ad8f62
Author: Giannis Adamopoulos <gadamopoulos(a)reactos.org>
AuthorDate: Sat Nov 11 13:56:28 2017 +0200
[COMCTL32] Button: Implement sending CDDS_PREERASE, CDDS_POSTERASE, CDDS_PREPAINT and
CDDS_POSTPAINT according to the apitest and the visual tests.
Remove some #ifdef __REACTOS__ from theme_button.c as this file has been forked for
good and there is not real plan to keep syncing it with wine.
---
dll/win32/comctl32/button.c | 58 +++++++++++++++++++++++++--
dll/win32/comctl32/theme_button.c | 83 ++++++++++++++++++---------------------
2 files changed, 94 insertions(+), 47 deletions(-)
diff --git a/dll/win32/comctl32/button.c b/dll/win32/comctl32/button.c
index 1ab1e765e5..4289b31e21 100644
--- a/dll/win32/comctl32/button.c
+++ b/dll/win32/comctl32/button.c
@@ -441,6 +441,35 @@ BOOL BUTTON_DrawIml(HDC hDC, BUTTON_IMAGELIST *pimlData, RECT *prc,
BOOL bOnlyCa
return TRUE;
}
+
+DWORD BUTTON_SendCustomDraw(HWND hwnd, HDC hDC, DWORD dwDrawStage, RECT* prc)
+{
+ NMCUSTOMDRAW nmcs;
+ LONG state = get_button_state( hwnd );
+
+ nmcs.hdr.hwndFrom = hwnd;
+ nmcs.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
+ nmcs.hdr.code = NM_CUSTOMDRAW ;
+ nmcs.dwDrawStage = dwDrawStage;
+ nmcs.hdc = hDC;
+ nmcs.rc = *prc;
+ nmcs.dwItemSpec = 0;
+ nmcs.uItemState = 0;
+ nmcs.lItemlParam = 0;
+ if(!IsWindowEnabled(hwnd))
+ nmcs.uItemState |= CDIS_DISABLED;
+ if (state & (BST_CHECKED | BST_INDETERMINATE))
+ nmcs.uItemState |= CDIS_CHECKED;
+ if (state & BST_FOCUS)
+ nmcs.uItemState |= CDIS_FOCUS;
+ if (state & BST_PUSHED)
+ nmcs.uItemState |= CDIS_SELECTED;
+ if (!(get_ui_state(hwnd) & UISF_HIDEACCEL))
+ nmcs.uItemState |= CDIS_SHOWKEYBOARDCUES;
+
+ return SendMessageW(GetParent(hwnd), WM_NOTIFY, nmcs.hdr.idFrom, (LPARAM)&nmcs);
+}
+
#endif
@@ -1417,6 +1446,9 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
BOOL pushedState = (state & BST_PUSHED);
HWND parent;
HRGN hrgn;
+#ifndef _USER32_
+ DWORD cdrf;
+#endif
GetClientRect( hwnd, &rc );
@@ -1440,6 +1472,15 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
hOldBrush = SelectObject(hDC,GetSysColorBrush(COLOR_BTNFACE));
oldBkMode = SetBkMode(hDC, TRANSPARENT);
+ /* completely skip the drawing if only focus has changed */
+ if (action == ODA_FOCUS) goto draw_focus;
+
+#ifndef _USER32_
+ cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREERASE, &rc);
+ if (cdrf == CDRF_SKIPDEFAULT)
+ goto cleanup;
+#endif
+
if (get_button_type(style) == BS_DEFPUSHBUTTON)
{
if (action != ODA_FOCUS)
@@ -1447,9 +1488,6 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
InflateRect( &rc, -1, -1 );
}
- /* completely skip the drawing if only focus has changed */
- if (action == ODA_FOCUS) goto draw_focus;
-
uState = DFCS_BUTTONPUSH;
if (style & BS_FLAT)
@@ -1467,6 +1505,15 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
+#ifndef _USER32_
+ if (cdrf == CDRF_NOTIFYPOSTERASE)
+ BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTERASE, &rc);
+
+ cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREPAINT, &rc);
+ if (cdrf == CDRF_SKIPDEFAULT)
+ goto cleanup;
+#endif
+
/* draw button label */
r = rc;
dtFlags = BUTTON_CalcLabelRect(hwnd, hDC, &r);
@@ -1483,6 +1530,11 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
SetTextColor( hDC, oldTxtColor );
+#ifndef _USER32_
+ if (cdrf == CDRF_NOTIFYPOSTPAINT)
+ BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTPAINT, &rc);
+#endif
+
draw_focus:
if (action == ODA_FOCUS || (state & BST_FOCUS))
{
diff --git a/dll/win32/comctl32/theme_button.c b/dll/win32/comctl32/theme_button.c
index daf5f1eb1b..9b85183799 100644
--- a/dll/win32/comctl32/theme_button.c
+++ b/dll/win32/comctl32/theme_button.c
@@ -57,6 +57,7 @@ static inline LONG_PTR get_button_image(HWND hwnd)
}
BOOL BUTTON_DrawIml(HDC hdc, BUTTON_IMAGELIST *pimlData, RECT *prc, BOOL bOnlyCalc);
+DWORD BUTTON_SendCustomDraw(HWND hwnd, HDC hDC, DWORD dwDrawStage, RECT* prc);
#endif
static UINT get_drawtext_flags(DWORD style, DWORD ex_style)
@@ -110,56 +111,48 @@ static inline WCHAR *get_button_text(HWND hwnd)
return text;
}
-#ifdef __REACTOS__ /* r73885 */
static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT
dtFlags, BOOL focused, LPARAM prfFlag)
-#else
-static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT
dtFlags, BOOL focused)
-#endif
{
static const int states[] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED,
PBS_DEFAULTED };
RECT bgRect, textRect;
-#ifdef __REACTOS__ /* r73885 */
HFONT font = get_button_font(hwnd);
-#else
- HFONT font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
-#endif
HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL;
int state = states[ drawState ];
- WCHAR *text = get_button_text(hwnd);
-#ifdef __REACTOS__ /* r74012 & r74406 */
+ WCHAR *text;
PBUTTON_DATA pdata = _GetButtonData(hwnd);
HWND parent;
- HBRUSH hBrush;
-#endif
+ DWORD cdrf;
GetClientRect(hwnd, &bgRect);
GetThemeBackgroundContentRect(theme, hDC, BP_PUSHBUTTON, state, &bgRect,
&textRect);
-#ifdef __REACTOS__ /* r73885 & r74149 */
if (prfFlag == 0)
{
if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state))
DrawThemeParentBackground(hwnd, hDC, NULL);
}
-#else
- if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state))
- DrawThemeParentBackground(hwnd, hDC, NULL);
-#endif
-#ifdef __REACTOS__ /* r74406 */
parent = GetParent(hwnd);
if (!parent) parent = hwnd;
- hBrush = (HBRUSH)SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)hwnd );
- FillRect( hDC, &bgRect, hBrush );
-#endif
+ SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)hwnd );
+
+ cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREERASE, &bgRect);
+ if (cdrf == CDRF_SKIPDEFAULT)
+ goto cleanup;
DrawThemeBackground(theme, hDC, BP_PUSHBUTTON, state, &bgRect, NULL);
-#ifdef __REACTOS__ /* r74012 */
+ if (cdrf == CDRF_NOTIFYPOSTERASE)
+ BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTERASE, &bgRect);
+
+ cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREPAINT, &bgRect);
+ if (cdrf == CDRF_SKIPDEFAULT)
+ goto cleanup;
+
BUTTON_DrawIml(hDC, &pdata->imlData, &textRect, FALSE);
-#endif
+ text = get_button_text(hwnd);
if (text)
{
DrawThemeText(theme, hDC, BP_PUSHBUTTON, state, text, lstrlenW(text), dtFlags, 0,
&textRect);
@@ -181,14 +174,14 @@ static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
DrawFocusRect( hDC, &focusRect );
}
+ if (cdrf == CDRF_NOTIFYPOSTPAINT)
+ BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTPAINT, &bgRect);
+
+cleanup:
if (hPrevFont) SelectObject(hDC, hPrevFont);
}
-#ifdef __REACTOS__ /* r73885 */
static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT
dtFlags, BOOL focused, LPARAM prfFlag)
-#else
-static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT
dtFlags, BOOL focused)
-#endif
{
static const int cb_states[3][5] =
{
@@ -206,11 +199,7 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
SIZE sz;
RECT bgRect, textRect;
HFONT font, hPrevFont = NULL;
-#ifdef __REACTOS__ /* r73885 */
LRESULT checkState = get_button_state(hwnd) & 3;
-#else
- LRESULT checkState = SendMessageW(hwnd, BM_GETCHECK, 0, 0);
-#endif
DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
int part = ((dwStyle & BUTTON_TYPE) == BS_RADIOBUTTON) || ((dwStyle &
BUTTON_TYPE) == BS_AUTORADIOBUTTON)
? BP_RADIOBUTTON
@@ -218,13 +207,12 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
int state = (part == BP_CHECKBOX)
? cb_states[ checkState ][ drawState ]
: rb_states[ checkState ][ drawState ];
- WCHAR *text = get_button_text(hwnd);
+ WCHAR *text;
LOGFONTW lf;
BOOL created_font = FALSE;
-#ifdef __REACTOS__ /* r74406 */
HWND parent;
HBRUSH hBrush;
-#endif
+ DWORD cdrf;
HRESULT hr = GetThemeFont(theme, hDC, part, state, TMT_FONT, &lf);
if (SUCCEEDED(hr)) {
@@ -237,11 +225,7 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
created_font = TRUE;
}
} else {
-#ifdef __REACTOS__ /* r73885 */
font = get_button_font(hwnd);
-#else
- font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
-#endif
hPrevFont = SelectObject(hDC, font);
}
@@ -250,7 +234,6 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
GetClientRect(hwnd, &bgRect);
-#ifdef __REACTOS__ /* r73885, r74149 and r74406 */
if (prfFlag == 0)
{
DrawThemeParentBackground(hwnd, hDC, NULL);
@@ -264,7 +247,10 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC,
(WPARAM)hDC, (LPARAM)hwnd );
FillRect( hDC, &bgRect, hBrush );
-#endif
+
+ cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREERASE, &bgRect);
+ if (cdrf == CDRF_SKIPDEFAULT)
+ goto cleanup;
GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect);
@@ -276,11 +262,16 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
bgRect.right = bgRect.left + sz.cx;
textRect.left = bgRect.right + 6;
-#ifndef __REACTOS__ /* r74406 */
- DrawThemeParentBackground(hwnd, hDC, NULL);
-#endif
-
DrawThemeBackground(theme, hDC, part, state, &bgRect, NULL);
+
+ if (cdrf == CDRF_NOTIFYPOSTERASE)
+ BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTERASE, &bgRect);
+
+ cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREPAINT, &bgRect);
+ if (cdrf == CDRF_SKIPDEFAULT)
+ goto cleanup;
+
+ text = get_button_text(hwnd);
if (text)
{
DrawThemeText(theme, hDC, part, state, text, lstrlenW(text), dtFlags, 0,
&textRect);
@@ -302,6 +293,10 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
HeapFree(GetProcessHeap(), 0, text);
}
+ if (cdrf == CDRF_NOTIFYPOSTPAINT)
+ BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTPAINT, &bgRect);
+
+cleanup:
if (created_font) DeleteObject(font);
if (hPrevFont) SelectObject(hDC, hPrevFont);
}