mirror of
https://github.com/reactos/reactos.git
synced 2025-06-25 12:49:46 +00:00
[COMCTL32] Implement using different image list images depending on the button state
This commit is contained in:
parent
3356f87b9e
commit
a4ea17218f
2 changed files with 39 additions and 161 deletions
|
@ -395,10 +395,10 @@ cleanup:
|
||||||
return ret;
|
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;
|
SIZE ImageSize;
|
||||||
int left, top;
|
int left, top, count;
|
||||||
|
|
||||||
if (!pimlData->himl)
|
if (!pimlData->himl)
|
||||||
return FALSE;
|
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;
|
top = prc->top + (prc->bottom - prc->top - ImageSize.cy) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bOnlyCalc)
|
if (bOnlyCalc)
|
||||||
ImageList_Draw(pimlData->himl, 0, hDC, left, top, 0);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1220,7 +1229,7 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _USER32_
|
#ifndef _USER32_
|
||||||
BOOL bHasIml = BUTTON_DrawIml(hdc, &pdata->imlData, &r, TRUE);
|
BOOL bHasIml = BUTTON_DrawIml(hdc, &pdata->imlData, &r, TRUE, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate label rectangle according to label type */
|
/* 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_
|
#ifndef _USER32_
|
||||||
PBUTTON_DATA pdata = _GetButtonData(hwnd);
|
PBUTTON_DATA pdata = _GetButtonData(hwnd);
|
||||||
BUTTON_DrawIml(hdc, &pdata->imlData, rc, FALSE);
|
BUTTON_DrawIml(hdc, &pdata->imlData, rc, FALSE, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((style & BS_PUSHLIKE) && (state & BST_INDETERMINATE))
|
if ((style & BS_PUSHLIKE) && (state & BST_INDETERMINATE))
|
||||||
|
|
|
@ -28,9 +28,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(theme_button);
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
STATE_NORMAL,
|
STATE_NORMAL,
|
||||||
STATE_DISABLED,
|
|
||||||
STATE_HOT,
|
STATE_HOT,
|
||||||
STATE_PRESSED,
|
STATE_PRESSED,
|
||||||
|
STATE_DISABLED,
|
||||||
STATE_DEFAULTED
|
STATE_DEFAULTED
|
||||||
} ButtonState;
|
} ButtonState;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ static inline LONG_PTR get_button_image(HWND hwnd)
|
||||||
return _GetButtonData(hwnd)->image;
|
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);
|
DWORD BUTTON_SendCustomDraw(HWND hwnd, HDC hDC, DWORD dwDrawStage, RECT* prc);
|
||||||
#endif
|
#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 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;
|
RECT bgRect, textRect;
|
||||||
HFONT font = get_button_font(hwnd);
|
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)
|
if (cdrf == CDRF_SKIPDEFAULT)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
BUTTON_DrawIml(hDC, &pdata->imlData, &textRect, FALSE);
|
BUTTON_DrawIml(hDC, &pdata->imlData, &textRect, FALSE, drawState);
|
||||||
|
|
||||||
text = get_button_text(hwnd);
|
text = get_button_text(hwnd);
|
||||||
if (text)
|
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] =
|
static const int cb_states[3][5] =
|
||||||
{
|
{
|
||||||
{ CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDNORMAL },
|
{ CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDNORMAL },
|
||||||
{ CBS_CHECKEDNORMAL, CBS_CHECKEDDISABLED, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDNORMAL },
|
{ CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDDISABLED, CBS_CHECKEDNORMAL },
|
||||||
{ CBS_MIXEDNORMAL, CBS_MIXEDDISABLED, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDNORMAL }
|
{ CBS_MIXEDNORMAL, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDDISABLED, CBS_MIXEDNORMAL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int rb_states[2][5] =
|
static const int rb_states[2][5] =
|
||||||
{
|
{
|
||||||
{ RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDNORMAL },
|
{ RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDNORMAL },
|
||||||
{ RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL }
|
{ RBS_CHECKEDNORMAL, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDDISABLED, RBS_CHECKEDNORMAL }
|
||||||
};
|
};
|
||||||
|
|
||||||
SIZE sz;
|
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)
|
static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused)
|
||||||
#endif
|
#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;
|
RECT bgRect, textRect, contentRect;
|
||||||
int state = states[ drawState ];
|
int state = states[ drawState ];
|
||||||
|
@ -415,30 +415,20 @@ static const pfThemedPaint btnThemedPaintFunc[BUTTON_TYPE + 1] =
|
||||||
NULL, /* Not defined */
|
NULL, /* Not defined */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __REACTOS__ /* r73873 */
|
|
||||||
BOOL BUTTON_PaintWithTheme(HTHEME theme, HWND hwnd, HDC hParamDC, LPARAM prfFlag)
|
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 dwStyle;
|
||||||
DWORD dwStyleEx;
|
DWORD dwStyleEx;
|
||||||
DWORD type;
|
DWORD type;
|
||||||
UINT dtFlags;
|
UINT dtFlags;
|
||||||
int state;
|
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;
|
ButtonState drawState;
|
||||||
#ifdef __REACTOS__ /* r73873, r73897, r73907 and r74120 */
|
|
||||||
pfThemedPaint paint;
|
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);
|
dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
|
||||||
type = dwStyle & BUTTON_TYPE;
|
type = dwStyle & BUTTON_TYPE;
|
||||||
|
|
||||||
|
@ -449,144 +439,23 @@ static BOOL BUTTON_Paint(HTHEME theme, HWND hwnd, HDC hParamDC)
|
||||||
if (!paint)
|
if (!paint)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (get_button_image(hwnd) != 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
dwStyleEx = GetWindowLongW(hwnd, GWL_EXSTYLE);
|
dwStyleEx = GetWindowLongW(hwnd, GWL_EXSTYLE);
|
||||||
dtFlags = get_drawtext_flags(dwStyle, dwStyleEx);
|
dtFlags = get_drawtext_flags(dwStyle, dwStyleEx);
|
||||||
state = get_button_state(hwnd);
|
state = get_button_state(hwnd);
|
||||||
#else
|
|
||||||
pfThemedPaint paint = btnThemedPaintFunc[ dwStyle & BUTTON_TYPE ];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(IsWindowEnabled(hwnd))
|
if(dwStyle & WS_DISABLED)
|
||||||
{
|
|
||||||
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
|
|
||||||
drawState = STATE_DISABLED;
|
drawState = STATE_DISABLED;
|
||||||
|
else if(state & BST_PUSHED)
|
||||||
#ifndef __REACTOS__ /* r73873 */
|
drawState = STATE_PRESSED;
|
||||||
hDC = hParamDC ? hParamDC : BeginPaint(hwnd, &ps);
|
else if ((dwStyle & BS_PUSHLIKE) && (state & (BST_CHECKED|BST_INDETERMINATE)))
|
||||||
if (paint) paint(theme, hwnd, hDC, drawState, dtFlags, state & BST_FOCUS);
|
drawState = STATE_PRESSED;
|
||||||
if (!hParamDC) EndPaint(hwnd, &ps);
|
else if(state & BST_HOT)
|
||||||
#endif
|
drawState = STATE_HOT;
|
||||||
|
else if((state & BST_FOCUS) || (dwStyle & BS_DEFPUSHBUTTON))
|
||||||
#ifdef __REACTOS__ /* r74074 & r74120 */
|
|
||||||
if (drawState == STATE_NORMAL && type == BS_DEFPUSHBUTTON)
|
|
||||||
{
|
|
||||||
drawState = STATE_DEFAULTED;
|
drawState = STATE_DEFAULTED;
|
||||||
}
|
else
|
||||||
#endif
|
drawState = STATE_NORMAL;
|
||||||
|
|
||||||
paint(theme, hwnd, hParamDC, drawState, dtFlags, state & BST_FOCUS, prfFlag);
|
paint(theme, hwnd, hParamDC, drawState, dtFlags, state & BST_FOCUS, prfFlag);
|
||||||
return TRUE;
|
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__ */
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue