From fa4183ef848fd53b492440f99a975e5e9ace86cd Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Wed, 5 Sep 2018 22:57:18 +0800 Subject: [PATCH] comctl32/button: Use get_draw_state() helper. Use a helper so that the get draw state routine can be shared by later code. Signed-off-by: Zhiyi Zhang Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/comctl32/button.c | 118 +++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 47 deletions(-) diff --git a/dlls/comctl32/button.c b/dlls/comctl32/button.c index 56968f99e39..6f9bc39de5d 100644 --- a/dlls/comctl32/button.c +++ b/dlls/comctl32/button.c @@ -128,15 +128,16 @@ static const WORD maxCheckState[MAX_BTN_TYPE] = BST_UNCHECKED /* BS_DEFCOMMANDLINK */ }; -/* These are indices into a states array to determine the theme state for a given theme part. */ -typedef enum +/* Generic draw states, use get_draw_state() to get specific state for button type */ +enum draw_state { STATE_NORMAL, STATE_DISABLED, STATE_HOT, STATE_PRESSED, - STATE_DEFAULTED -} ButtonState; + STATE_DEFAULTED, + DRAW_STATE_COUNT +}; typedef void (*pfPaint)( const BUTTON_INFO *infoPtr, HDC hdc, UINT action ); @@ -160,11 +161,11 @@ static const pfPaint btnPaintFunc[MAX_BTN_TYPE] = PB_Paint /* BS_DEFCOMMANDLINK */ }; -typedef void (*pfThemedPaint)( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); +typedef void (*pfThemedPaint)( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, int drawState, UINT dtflags, BOOL focused); -static void PB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); -static void CB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); -static void GB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused); +static void PB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, int drawState, UINT dtflags, BOOL focused); +static void CB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, int drawState, UINT dtflags, BOOL focused); +static void GB_ThemedPaint( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, int drawState, UINT dtflags, BOOL focused); static const pfThemedPaint btnThemedPaintFunc[MAX_BTN_TYPE] = { @@ -286,6 +287,63 @@ static UINT BUTTON_BStoDT( DWORD style, DWORD ex_style ) return dtStyle; } +static int get_draw_state(const BUTTON_INFO *infoPtr) +{ + static const int pb_states[DRAW_STATE_COUNT] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED, PBS_DEFAULTED }; + static const int cb_states[3][DRAW_STATE_COUNT] = + { + { 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 } + }; + static const int rb_states[2][DRAW_STATE_COUNT] = + { + { RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDNORMAL }, + { RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL } + }; + static const int gb_states[DRAW_STATE_COUNT] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL, GBS_NORMAL }; + LONG style = GetWindowLongW(infoPtr->hwnd, GWL_STYLE); + UINT type = get_button_type(style); + int check_state = infoPtr->state & 3; + enum draw_state state; + + if (!IsWindowEnabled(infoPtr->hwnd)) + state = STATE_DISABLED; + else if (infoPtr->state & BST_PUSHED) + state = STATE_PRESSED; + else if (infoPtr->state & BST_HOT) + state = STATE_HOT; + else if (infoPtr->state & BST_FOCUS) + state = STATE_DEFAULTED; + else + state = STATE_NORMAL; + + switch (type) + { + case BS_PUSHBUTTON: + case BS_DEFPUSHBUTTON: + case BS_USERBUTTON: + case BS_SPLITBUTTON: + case BS_DEFSPLITBUTTON: + case BS_COMMANDLINK: + case BS_DEFCOMMANDLINK: + return pb_states[state]; + case BS_CHECKBOX: + case BS_AUTOCHECKBOX: + return cb_states[check_state][state]; + case BS_RADIOBUTTON: + case BS_3STATE: + case BS_AUTO3STATE: + case BS_AUTORADIOBUTTON: + return rb_states[check_state][state]; + case BS_GROUPBOX: + return gb_states[state]; + default: + WARN("Unsupported button type 0x%08x\n", type); + return PBS_NORMAL; + } +} + static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { BUTTON_INFO *infoPtr = (BUTTON_INFO *)GetWindowLongPtrW(hWnd, 0); @@ -402,20 +460,9 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L if (theme && btnThemedPaintFunc[btn_type]) { - ButtonState drawState; - UINT dtflags; + int drawState = get_draw_state(infoPtr); + UINT dtflags = BUTTON_BStoDT(style, GetWindowLongW(hWnd, GWL_EXSTYLE)); - if (IsWindowEnabled( hWnd )) - { - if (infoPtr->state & BST_PUSHED) drawState = STATE_PRESSED; - else if (infoPtr->state & BST_HOT) drawState = STATE_HOT; - else if (infoPtr->state & BST_FOCUS) drawState = STATE_DEFAULTED; - else drawState = STATE_NORMAL; - } - else - drawState = STATE_DISABLED; - - dtflags = BUTTON_BStoDT(style, GetWindowLongW(hWnd, GWL_EXSTYLE)); btnThemedPaintFunc[btn_type](theme, infoPtr, hdc, drawState, dtflags, infoPtr->state & BST_FOCUS); } else if (btnPaintFunc[btn_type]) @@ -1352,14 +1399,11 @@ static void OB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action ) if (hrgn) DeleteObject( hrgn ); } -static void PB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) +static void PB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, int state, UINT dtFlags, BOOL focused) { - static const int states[] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED, PBS_DEFAULTED }; - RECT bgRect, textRect; HFONT font = infoPtr->font; HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL; - int state = states[ drawState ]; WCHAR *text = get_button_text(infoPtr); GetClientRect(infoPtr->hwnd, &bgRect); @@ -1392,31 +1436,14 @@ static void PB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, Bu if (hPrevFont) SelectObject(hDC, hPrevFont); } -static void CB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) +static void CB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, int state, UINT dtFlags, BOOL focused) { - 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 } - }; - - 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 } - }; - SIZE sz; RECT bgRect, textRect; HFONT font, hPrevFont = NULL; - int checkState = infoPtr->state & 3; DWORD dwStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE); UINT btn_type = get_button_type( dwStyle ); int part = (btn_type == BS_RADIOBUTTON) || (btn_type == BS_AUTORADIOBUTTON) ? BP_RADIOBUTTON : BP_CHECKBOX; - int state = (part == BP_CHECKBOX) - ? cb_states[ checkState ][ drawState ] - : rb_states[ checkState ][ drawState ]; WCHAR *text = get_button_text(infoPtr); LOGFONTW lf; BOOL created_font = FALSE; @@ -1478,12 +1505,9 @@ static void CB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, Bu if (hPrevFont) SelectObject(hDC, hPrevFont); } -static void GB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) +static void GB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, int state, UINT dtFlags, BOOL focused) { - static const int states[] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL, GBS_NORMAL }; - RECT bgRect, textRect, contentRect; - int state = states[ drawState ]; WCHAR *text = get_button_text(infoPtr); LOGFONTW lf; HFONT font, hPrevFont = NULL;