https://git.reactos.org/?p=reactos.git;a=commitdiff;h=18dee7a39228f11ade4d95...
commit 18dee7a39228f11ade4d95d1e2715672c3ad8f62 Author: Giannis Adamopoulos gadamopoulos@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); }