https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a4ea17218f3062e7089d5…
commit a4ea17218f3062e7089d5913985473f78f284cbf
Author: Giannis Adamopoulos <gadamopoulos(a)reactos.org>
AuthorDate: Fri Nov 17 14:00:30 2017 +0200
[COMCTL32] Implement using different image list images depending on the button state
---
dll/win32/comctl32/button.c | 21 +++--
dll/win32/comctl32/theme_button.c | 179 +++++---------------------------------
2 files changed, 39 insertions(+), 161 deletions(-)
diff --git a/dll/win32/comctl32/button.c b/dll/win32/comctl32/button.c
index eb627145f3..bdc91840d5 100644
--- a/dll/win32/comctl32/button.c
+++ b/dll/win32/comctl32/button.c
@@ -395,10 +395,10 @@ cleanup:
return ret;
}
-BOOL BUTTON_DrawIml(HDC hDC, BUTTON_IMAGELIST *pimlData, RECT *prc, BOOL bOnlyCalc)
+BOOL BUTTON_DrawIml(HDC hDC, BUTTON_IMAGELIST *pimlData, RECT *prc, BOOL bOnlyCalc, int
index)
{
SIZE ImageSize;
- int left, top;
+ int left, top, count;
if (!pimlData->himl)
return FALSE;
@@ -436,8 +436,17 @@ BOOL BUTTON_DrawIml(HDC hDC, BUTTON_IMAGELIST *pimlData, RECT *prc,
BOOL bOnlyCa
top = prc->top + (prc->bottom - prc->top - ImageSize.cy) / 2;
}
- if (!bOnlyCalc)
- ImageList_Draw(pimlData->himl, 0, hDC, left, top, 0);
+ if (bOnlyCalc)
+ return TRUE;
+
+ count = ImageList_GetImageCount(pimlData->himl);
+
+ if (count == 1)
+ index = 0;
+ else if (index >= count)
+ return TRUE;
+
+ ImageList_Draw(pimlData->himl, index, hDC, left, top, 0);
return TRUE;
}
@@ -1220,7 +1229,7 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
#endif
#ifndef _USER32_
- BOOL bHasIml = BUTTON_DrawIml(hdc, &pdata->imlData, &r, TRUE);
+ BOOL bHasIml = BUTTON_DrawIml(hdc, &pdata->imlData, &r, TRUE, 0);
#endif
/* Calculate label rectangle according to label type */
@@ -1378,7 +1387,7 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, RECT
*rc)
#ifndef _USER32_
PBUTTON_DATA pdata = _GetButtonData(hwnd);
- BUTTON_DrawIml(hdc, &pdata->imlData, rc, FALSE);
+ BUTTON_DrawIml(hdc, &pdata->imlData, rc, FALSE, 0);
#endif
if ((style & BS_PUSHLIKE) && (state & BST_INDETERMINATE))
diff --git a/dll/win32/comctl32/theme_button.c b/dll/win32/comctl32/theme_button.c
index 9b85183799..755f4a7f06 100644
--- a/dll/win32/comctl32/theme_button.c
+++ b/dll/win32/comctl32/theme_button.c
@@ -28,9 +28,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(theme_button);
typedef enum
{
STATE_NORMAL,
- STATE_DISABLED,
STATE_HOT,
STATE_PRESSED,
+ STATE_DISABLED,
STATE_DEFAULTED
} ButtonState;
@@ -56,7 +56,7 @@ static inline LONG_PTR get_button_image(HWND hwnd)
return _GetButtonData(hwnd)->image;
}
-BOOL BUTTON_DrawIml(HDC hdc, BUTTON_IMAGELIST *pimlData, RECT *prc, BOOL bOnlyCalc);
+BOOL BUTTON_DrawIml(HDC hdc, BUTTON_IMAGELIST *pimlData, RECT *prc, BOOL bOnlyCalc, int
index);
DWORD BUTTON_SendCustomDraw(HWND hwnd, HDC hDC, DWORD dwDrawStage, RECT* prc);
#endif
@@ -113,7 +113,7 @@ static inline WCHAR *get_button_text(HWND hwnd)
static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT
dtFlags, BOOL focused, LPARAM prfFlag)
{
- static const int states[] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED,
PBS_DEFAULTED };
+ static const int states[] = { PBS_NORMAL, PBS_HOT, PBS_PRESSED, PBS_DISABLED,
PBS_DEFAULTED };
RECT bgRect, textRect;
HFONT font = get_button_font(hwnd);
@@ -150,7 +150,7 @@ static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
if (cdrf == CDRF_SKIPDEFAULT)
goto cleanup;
- BUTTON_DrawIml(hDC, &pdata->imlData, &textRect, FALSE);
+ BUTTON_DrawIml(hDC, &pdata->imlData, &textRect, FALSE, drawState);
text = get_button_text(hwnd);
if (text)
@@ -185,15 +185,15 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
{
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 }
+ { CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED,
CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDNORMAL },
+ { CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDDISABLED,
CBS_CHECKEDNORMAL },
+ { CBS_MIXEDNORMAL, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDDISABLED,
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 }
+ { RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED,
RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDNORMAL },
+ { RBS_CHECKEDNORMAL, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDDISABLED,
RBS_CHECKEDNORMAL }
};
SIZE sz;
@@ -307,7 +307,7 @@ static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState
drawState, UIN
static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT
dtFlags, BOOL focused)
#endif
{
- static const int states[] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL,
GBS_NORMAL };
+ static const int states[] = { GBS_NORMAL, GBS_NORMAL, GBS_NORMAL, GBS_DISABLED,
GBS_NORMAL };
RECT bgRect, textRect, contentRect;
int state = states[ drawState ];
@@ -415,30 +415,20 @@ static const pfThemedPaint btnThemedPaintFunc[BUTTON_TYPE + 1] =
NULL, /* Not defined */
};
-#ifdef __REACTOS__ /* r73873 */
BOOL BUTTON_PaintWithTheme(HTHEME theme, HWND hwnd, HDC hParamDC, LPARAM prfFlag)
-#else
-static BOOL BUTTON_Paint(HTHEME theme, HWND hwnd, HDC hParamDC)
-#endif
{
-#ifdef __REACTOS__ /* r73873, r73897 and r74120 */
DWORD dwStyle;
DWORD dwStyleEx;
DWORD type;
UINT dtFlags;
int state;
-#else
- 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);
-#endif
ButtonState drawState;
-#ifdef __REACTOS__ /* r73873, r73897, r73907 and r74120 */
pfThemedPaint paint;
+ /* Don't draw with themes on a button with BS_ICON or BS_BITMAP */
+ if (get_button_image(hwnd) != 0)
+ return FALSE;
+
dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
type = dwStyle & BUTTON_TYPE;
@@ -449,144 +439,23 @@ static BOOL BUTTON_Paint(HTHEME theme, HWND hwnd, HDC hParamDC)
if (!paint)
return FALSE;
- if (get_button_image(hwnd) != 0)
- return FALSE;
-
dwStyleEx = GetWindowLongW(hwnd, GWL_EXSTYLE);
dtFlags = get_drawtext_flags(dwStyle, dwStyleEx);
state = get_button_state(hwnd);
-#else
- pfThemedPaint paint = btnThemedPaintFunc[ dwStyle & BUTTON_TYPE ];
-#endif
- if(IsWindowEnabled(hwnd))
- {
- if(state & BST_PUSHED)
- drawState = STATE_PRESSED;
- else if ((dwStyle & BS_PUSHLIKE) && (state &
(BST_CHECKED|BST_INDETERMINATE)))
- drawState = STATE_PRESSED;
- else if(state & BST_HOT)
- drawState = STATE_HOT;
- else if(state & BST_FOCUS)
- drawState = STATE_DEFAULTED;
- else
- drawState = STATE_NORMAL;
- }
- else
+ if(dwStyle & WS_DISABLED)
drawState = STATE_DISABLED;
-
-#ifndef __REACTOS__ /* r73873 */
- hDC = hParamDC ? hParamDC : BeginPaint(hwnd, &ps);
- if (paint) paint(theme, hwnd, hDC, drawState, dtFlags, state & BST_FOCUS);
- if (!hParamDC) EndPaint(hwnd, &ps);
-#endif
-
-#ifdef __REACTOS__ /* r74074 & r74120 */
- if (drawState == STATE_NORMAL && type == BS_DEFPUSHBUTTON)
- {
+ else if(state & BST_PUSHED)
+ drawState = STATE_PRESSED;
+ else if ((dwStyle & BS_PUSHLIKE) && (state &
(BST_CHECKED|BST_INDETERMINATE)))
+ drawState = STATE_PRESSED;
+ else if(state & BST_HOT)
+ drawState = STATE_HOT;
+ else if((state & BST_FOCUS) || (dwStyle & BS_DEFPUSHBUTTON))
drawState = STATE_DEFAULTED;
- }
-#endif
+ else
+ drawState = STATE_NORMAL;
paint(theme, hwnd, hParamDC, drawState, dtFlags, state & BST_FOCUS, prfFlag);
return TRUE;
}
-
-#ifndef __REACTOS__ /* r73873 */
-/**********************************************************************
- * 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;
- }
-
- case BM_SETCHECK:
- case BM_SETSTATE:
- theme = GetWindowTheme(hwnd);
- if (theme) {
- InvalidateRect(hwnd, NULL, FALSE);
- }
- return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
-
- default:
- /* Call old proc */
- return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
- }
- return 0;
-}
-#endif /* !__REACTOS__ */