comctl32/button: Use allocated structure to keep control data.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8874a6ecc3
commit
6e55073574
|
@ -73,12 +73,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(button);
|
||||
|
||||
/* GetWindowLong offsets for window extra information */
|
||||
#define STATE_GWL_OFFSET 0
|
||||
#define HFONT_GWL_OFFSET (sizeof(LONG))
|
||||
#define HIMAGE_GWL_OFFSET (HFONT_GWL_OFFSET+sizeof(HFONT))
|
||||
#define NB_EXTRA_BYTES (HIMAGE_GWL_OFFSET+sizeof(HANDLE))
|
||||
|
||||
/* undocumented flags */
|
||||
#define BUTTON_NSTATES 0x0F
|
||||
#define BUTTON_BTNPRESSED 0x40
|
||||
|
@ -93,12 +87,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(button);
|
|||
(LPARAM)(hWnd)); \
|
||||
} while(0)
|
||||
|
||||
static UINT BUTTON_CalcLabelRect( HWND hwnd, HDC hdc, RECT *rc );
|
||||
static void PB_Paint( HWND hwnd, HDC hDC, UINT action );
|
||||
static void CB_Paint( HWND hwnd, HDC hDC, UINT action );
|
||||
static void GB_Paint( HWND hwnd, HDC hDC, UINT action );
|
||||
static void UB_Paint( HWND hwnd, HDC hDC, UINT action );
|
||||
static void OB_Paint( HWND hwnd, HDC hDC, UINT action );
|
||||
typedef struct _BUTTON_INFO
|
||||
{
|
||||
HWND hwnd;
|
||||
LONG state;
|
||||
HFONT font;
|
||||
union
|
||||
{
|
||||
HICON icon;
|
||||
HBITMAP bitmap;
|
||||
HANDLE image;
|
||||
} u;
|
||||
} BUTTON_INFO;
|
||||
|
||||
static UINT BUTTON_CalcLabelRect( const BUTTON_INFO *infoPtr, HDC hdc, RECT *rc );
|
||||
static void PB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action );
|
||||
static void CB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action );
|
||||
static void GB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action );
|
||||
static void UB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action );
|
||||
static void OB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action );
|
||||
static void BUTTON_CheckAutoRadioButton( HWND hwnd );
|
||||
|
||||
#define MAX_BTN_TYPE 16
|
||||
|
@ -133,7 +140,7 @@ typedef enum
|
|||
STATE_DEFAULTED
|
||||
} ButtonState;
|
||||
|
||||
typedef void (*pfPaint)( HWND hwnd, HDC hdc, UINT action );
|
||||
typedef void (*pfPaint)( const BUTTON_INFO *infoPtr, HDC hdc, UINT action );
|
||||
|
||||
static const pfPaint btnPaintFunc[MAX_BTN_TYPE] =
|
||||
{
|
||||
|
@ -155,11 +162,11 @@ static const pfPaint btnPaintFunc[MAX_BTN_TYPE] =
|
|||
PB_Paint /* BS_DEFCOMMANDLINK */
|
||||
};
|
||||
|
||||
typedef void (*pfThemedPaint)( HTHEME theme, HWND hwnd, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused);
|
||||
typedef void (*pfThemedPaint)( HTHEME theme, const BUTTON_INFO *infoPtr, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused);
|
||||
|
||||
static void PB_ThemedPaint( HTHEME theme, HWND hwnd, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused);
|
||||
static void CB_ThemedPaint( HTHEME theme, HWND hwnd, HDC hdc, ButtonState drawState, UINT dtflags, BOOL focused);
|
||||
static void GB_ThemedPaint( HTHEME theme, HWND hwnd, HDC hdc, ButtonState 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 const pfThemedPaint btnThemedPaintFunc[MAX_BTN_TYPE] =
|
||||
{
|
||||
|
@ -181,53 +188,29 @@ static const pfThemedPaint btnThemedPaintFunc[MAX_BTN_TYPE] =
|
|||
NULL, /* BS_DEFCOMMANDLINK */
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* button class descriptor
|
||||
*/
|
||||
|
||||
static inline LONG get_button_state( HWND hwnd )
|
||||
{
|
||||
return GetWindowLongW( hwnd, STATE_GWL_OFFSET );
|
||||
}
|
||||
|
||||
static inline void set_button_state( HWND hwnd, LONG state )
|
||||
{
|
||||
SetWindowLongW( hwnd, STATE_GWL_OFFSET, state );
|
||||
}
|
||||
|
||||
static inline HFONT get_button_font( HWND hwnd )
|
||||
{
|
||||
return (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
|
||||
}
|
||||
|
||||
static inline void set_button_font( HWND hwnd, HFONT font )
|
||||
{
|
||||
SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, (LONG_PTR)font );
|
||||
}
|
||||
|
||||
static inline UINT get_button_type( LONG window_style )
|
||||
{
|
||||
return (window_style & BS_TYPEMASK);
|
||||
}
|
||||
|
||||
/* paint a button of any type */
|
||||
static inline void paint_button( HWND hwnd, LONG style, UINT action )
|
||||
static inline void paint_button( BUTTON_INFO *infoPtr, LONG style, UINT action )
|
||||
{
|
||||
if (btnPaintFunc[style] && IsWindowVisible(hwnd))
|
||||
if (btnPaintFunc[style] && IsWindowVisible(infoPtr->hwnd))
|
||||
{
|
||||
HDC hdc = GetDC( hwnd );
|
||||
btnPaintFunc[style]( hwnd, hdc, action );
|
||||
ReleaseDC( hwnd, hdc );
|
||||
HDC hdc = GetDC( infoPtr->hwnd );
|
||||
btnPaintFunc[style]( infoPtr, hdc, action );
|
||||
ReleaseDC( infoPtr->hwnd, hdc );
|
||||
}
|
||||
}
|
||||
|
||||
/* retrieve the button text; returned buffer must be freed by caller */
|
||||
static inline WCHAR *get_button_text( HWND hwnd )
|
||||
static inline WCHAR *get_button_text( const BUTTON_INFO *infoPtr )
|
||||
{
|
||||
INT len = GetWindowTextLengthW( hwnd );
|
||||
INT len = GetWindowTextLengthW( infoPtr->hwnd );
|
||||
WCHAR *buffer = heap_alloc( (len + 1) * sizeof(WCHAR) );
|
||||
if (buffer)
|
||||
GetWindowTextW( hwnd, buffer, len + 1 );
|
||||
GetWindowTextW( infoPtr->hwnd, buffer, len + 1 );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -300,9 +283,9 @@ static UINT BUTTON_BStoDT( DWORD style, DWORD ex_style )
|
|||
return dtStyle;
|
||||
}
|
||||
|
||||
|
||||
static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
BUTTON_INFO *infoPtr = (BUTTON_INFO *)GetWindowLongPtrW(hWnd, 0);
|
||||
RECT rect;
|
||||
POINT pt;
|
||||
LONG style = GetWindowLongW( hWnd, GWL_STYLE );
|
||||
|
@ -313,6 +296,9 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
|
||||
if (!IsWindow( hWnd )) return 0;
|
||||
|
||||
if (!infoPtr && (uMsg != WM_NCCREATE))
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
|
||||
pt.x = (short)LOWORD(lParam);
|
||||
pt.y = (short)HIWORD(lParam);
|
||||
|
||||
|
@ -339,7 +325,18 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
if (theme)
|
||||
RedrawWindow( hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW );
|
||||
else
|
||||
paint_button( hWnd, btn_type, ODA_DRAWENTIRE );
|
||||
paint_button( infoPtr, btn_type, ODA_DRAWENTIRE );
|
||||
break;
|
||||
|
||||
case WM_NCCREATE:
|
||||
infoPtr = heap_alloc_zero( sizeof(*infoPtr) );
|
||||
SetWindowLongPtrW( hWnd, 0, (LONG_PTR)infoPtr );
|
||||
infoPtr->hwnd = hWnd;
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
|
||||
case WM_NCDESTROY:
|
||||
SetWindowLongPtrW( hWnd, 0, 0 );
|
||||
heap_free(infoPtr);
|
||||
break;
|
||||
|
||||
case WM_CREATE:
|
||||
|
@ -352,7 +349,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
style = (style & ~BS_TYPEMASK) | BS_PUSHBUTTON;
|
||||
SetWindowLongW( hWnd, GWL_STYLE, style );
|
||||
}
|
||||
set_button_state( hWnd, BST_UNCHECKED );
|
||||
infoPtr->state = BST_UNCHECKED;
|
||||
OpenThemeData( hWnd, WC_BUTTONW );
|
||||
return 0;
|
||||
|
||||
|
@ -398,24 +395,23 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
ButtonState drawState;
|
||||
UINT dtflags;
|
||||
|
||||
state = get_button_state( hWnd );
|
||||
if (IsWindowEnabled( hWnd ))
|
||||
{
|
||||
if (state & BST_PUSHED) drawState = STATE_PRESSED;
|
||||
else if (state & BST_HOT) drawState = STATE_HOT;
|
||||
else if (state & BST_FOCUS) drawState = STATE_DEFAULTED;
|
||||
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, hWnd, hdc, drawState, dtflags, state & BST_FOCUS);
|
||||
btnThemedPaintFunc[btn_type](theme, infoPtr, hdc, drawState, dtflags, infoPtr->state & BST_FOCUS);
|
||||
}
|
||||
else if (btnPaintFunc[btn_type])
|
||||
{
|
||||
int nOldMode = SetBkMode( hdc, OPAQUE );
|
||||
(btnPaintFunc[btn_type])( hWnd, hdc, ODA_DRAWENTIRE );
|
||||
btnPaintFunc[btn_type]( infoPtr, hdc, ODA_DRAWENTIRE );
|
||||
SetBkMode(hdc, nOldMode); /* reset painting mode */
|
||||
}
|
||||
|
||||
|
@ -427,7 +423,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
if (wParam == VK_SPACE)
|
||||
{
|
||||
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
|
||||
set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED );
|
||||
infoPtr->state |= BUTTON_BTNPRESSED;
|
||||
SetCapture( hWnd );
|
||||
}
|
||||
break;
|
||||
|
@ -445,7 +441,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
case WM_LBUTTONDOWN:
|
||||
SetCapture( hWnd );
|
||||
SetFocus( hWnd );
|
||||
set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED );
|
||||
infoPtr->state |= BUTTON_BTNPRESSED;
|
||||
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
|
||||
break;
|
||||
|
||||
|
@ -454,10 +450,9 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
break;
|
||||
/* fall through */
|
||||
case WM_LBUTTONUP:
|
||||
state = get_button_state( hWnd );
|
||||
state = infoPtr->state;
|
||||
if (!(state & BUTTON_BTNPRESSED)) break;
|
||||
state &= BUTTON_NSTATES;
|
||||
set_button_state( hWnd, state );
|
||||
infoPtr->state &= BUTTON_NSTATES;
|
||||
if (!(state & BST_PUSHED))
|
||||
{
|
||||
ReleaseCapture();
|
||||
|
@ -467,18 +462,17 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
GetClientRect( hWnd, &rect );
|
||||
if (uMsg == WM_KEYUP || PtInRect( &rect, pt ))
|
||||
{
|
||||
state = get_button_state( hWnd );
|
||||
switch(btn_type)
|
||||
{
|
||||
case BS_AUTOCHECKBOX:
|
||||
SendMessageW( hWnd, BM_SETCHECK, !(state & BST_CHECKED), 0 );
|
||||
SendMessageW( hWnd, BM_SETCHECK, !(infoPtr->state & BST_CHECKED), 0 );
|
||||
break;
|
||||
case BS_AUTORADIOBUTTON:
|
||||
SendMessageW( hWnd, BM_SETCHECK, TRUE, 0 );
|
||||
break;
|
||||
case BS_AUTO3STATE:
|
||||
SendMessageW( hWnd, BM_SETCHECK,
|
||||
(state & BST_INDETERMINATE) ? 0 : ((state & 3) + 1), 0 );
|
||||
SendMessageW( hWnd, BM_SETCHECK, (infoPtr->state & BST_INDETERMINATE) ? 0 :
|
||||
((infoPtr->state & 3) + 1), 0 );
|
||||
break;
|
||||
}
|
||||
ReleaseCapture();
|
||||
|
@ -493,12 +487,11 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
case WM_CAPTURECHANGED:
|
||||
TRACE("WM_CAPTURECHANGED %p\n", hWnd);
|
||||
if (hWnd == (HWND)lParam) break;
|
||||
state = get_button_state( hWnd );
|
||||
if (state & BUTTON_BTNPRESSED)
|
||||
if (infoPtr->state & BUTTON_BTNPRESSED)
|
||||
{
|
||||
state &= BUTTON_NSTATES;
|
||||
set_button_state( hWnd, state );
|
||||
if (state & BST_PUSHED) SendMessageW( hWnd, BM_SETSTATE, FALSE, 0 );
|
||||
infoPtr->state &= BUTTON_NSTATES;
|
||||
if (infoPtr->state & BST_PUSHED)
|
||||
SendMessageW( hWnd, BM_SETSTATE, FALSE, 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -526,14 +519,14 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
|
||||
case WM_MOUSEHOVER:
|
||||
{
|
||||
set_button_state( hWnd, get_button_state( hWnd ) | BST_HOT );
|
||||
infoPtr->state |= BST_HOT;
|
||||
InvalidateRect( hWnd, NULL, FALSE );
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
{
|
||||
set_button_state( hWnd, get_button_state( hWnd ) & ~BST_HOT );
|
||||
infoPtr->state &= ~BST_HOT;
|
||||
InvalidateRect( hWnd, NULL, FALSE );
|
||||
break;
|
||||
}
|
||||
|
@ -565,7 +558,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
/* FIXME: check other BS_* handlers */
|
||||
if (btn_type == BS_GROUPBOX)
|
||||
InflateRect(&rc, -7, 1); /* GB_Paint does this */
|
||||
BUTTON_CalcLabelRect(hWnd, hdc, &rc);
|
||||
BUTTON_CalcLabelRect(infoPtr, hdc, &rc);
|
||||
/* Clip by client rect bounds */
|
||||
if (rc.right > client.right) rc.right = client.right;
|
||||
if (rc.bottom > client.bottom) rc.bottom = client.bottom;
|
||||
|
@ -577,33 +570,32 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
if (btn_type == BS_GROUPBOX) /* Yes, only for BS_GROUPBOX */
|
||||
InvalidateRect( hWnd, NULL, TRUE );
|
||||
else
|
||||
paint_button( hWnd, btn_type, ODA_DRAWENTIRE );
|
||||
paint_button( infoPtr, btn_type, ODA_DRAWENTIRE );
|
||||
return 1; /* success. FIXME: check text length */
|
||||
}
|
||||
|
||||
case WM_SETFONT:
|
||||
set_button_font( hWnd, (HFONT)wParam );
|
||||
infoPtr->font = (HFONT)wParam;
|
||||
if (lParam) InvalidateRect(hWnd, NULL, TRUE);
|
||||
break;
|
||||
|
||||
case WM_GETFONT:
|
||||
return (LRESULT)get_button_font( hWnd );
|
||||
return (LRESULT)infoPtr->font;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
TRACE("WM_SETFOCUS %p\n",hWnd);
|
||||
set_button_state( hWnd, get_button_state(hWnd) | BST_FOCUS );
|
||||
paint_button( hWnd, btn_type, ODA_FOCUS );
|
||||
infoPtr->state |= BST_FOCUS;
|
||||
paint_button( infoPtr, btn_type, ODA_FOCUS );
|
||||
if (style & BS_NOTIFY)
|
||||
BUTTON_NOTIFY_PARENT(hWnd, BN_SETFOCUS);
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
TRACE("WM_KILLFOCUS %p\n",hWnd);
|
||||
state = get_button_state( hWnd );
|
||||
set_button_state( hWnd, state & ~BST_FOCUS );
|
||||
paint_button( hWnd, btn_type, ODA_FOCUS );
|
||||
infoPtr->state &= ~BST_FOCUS;
|
||||
paint_button( infoPtr, btn_type, ODA_FOCUS );
|
||||
|
||||
if ((state & BUTTON_BTNPRESSED) && GetCapture() == hWnd)
|
||||
if ((infoPtr->state & BUTTON_BTNPRESSED) && GetCapture() == hWnd)
|
||||
ReleaseCapture();
|
||||
if (style & BS_NOTIFY)
|
||||
BUTTON_NOTIFY_PARENT(hWnd, BN_KILLFOCUS);
|
||||
|
@ -644,27 +636,27 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
default:
|
||||
return 0;
|
||||
}
|
||||
oldHbitmap = (HBITMAP)SetWindowLongPtrW( hWnd, HIMAGE_GWL_OFFSET, lParam );
|
||||
oldHbitmap = infoPtr->u.image;
|
||||
infoPtr->u.image = (HANDLE)lParam;
|
||||
InvalidateRect( hWnd, NULL, FALSE );
|
||||
return (LRESULT)oldHbitmap;
|
||||
|
||||
case BM_GETIMAGE:
|
||||
return GetWindowLongPtrW( hWnd, HIMAGE_GWL_OFFSET );
|
||||
return (LRESULT)infoPtr->u.image;
|
||||
|
||||
case BM_GETCHECK:
|
||||
return get_button_state( hWnd ) & 3;
|
||||
return infoPtr->state & 3;
|
||||
|
||||
case BM_SETCHECK:
|
||||
if (wParam > maxCheckState[btn_type]) wParam = maxCheckState[btn_type];
|
||||
state = get_button_state( hWnd );
|
||||
if ((btn_type == BS_RADIOBUTTON) || (btn_type == BS_AUTORADIOBUTTON))
|
||||
{
|
||||
style = wParam ? style | WS_TABSTOP : style & ~WS_TABSTOP;
|
||||
SetWindowLongW( hWnd, GWL_STYLE, style );
|
||||
}
|
||||
if ((state & 3) != wParam)
|
||||
if ((infoPtr->state & 3) != wParam)
|
||||
{
|
||||
set_button_state( hWnd, (state & ~3) | wParam );
|
||||
infoPtr->state = (infoPtr->state & ~3) | wParam;
|
||||
InvalidateRect( hWnd, NULL, FALSE );
|
||||
}
|
||||
if ((btn_type == BS_AUTORADIOBUTTON) && (wParam == BST_CHECKED) && (style & WS_CHILD))
|
||||
|
@ -672,10 +664,10 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
break;
|
||||
|
||||
case BM_GETSTATE:
|
||||
return get_button_state( hWnd );
|
||||
return infoPtr->state;
|
||||
|
||||
case BM_SETSTATE:
|
||||
state = get_button_state( hWnd );
|
||||
state = infoPtr->state;
|
||||
new_state = wParam ? BST_PUSHED : 0;
|
||||
|
||||
if ((state ^ new_state) & BST_PUSHED)
|
||||
|
@ -687,7 +679,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
|
||||
if (btn_type == BS_USERBUTTON)
|
||||
BUTTON_NOTIFY_PARENT( hWnd, (state & BST_PUSHED) ? BN_HILITE : BN_UNHILITE );
|
||||
set_button_state( hWnd, state );
|
||||
infoPtr->state = state;
|
||||
|
||||
InvalidateRect( hWnd, NULL, FALSE );
|
||||
}
|
||||
|
@ -712,10 +704,10 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
|
|||
* (pushed, etc.). If there is nothing to draw (no text/image) output
|
||||
* rectangle is empty, and return value is (UINT)-1.
|
||||
*/
|
||||
static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
||||
static UINT BUTTON_CalcLabelRect(const BUTTON_INFO *infoPtr, HDC hdc, RECT *rc)
|
||||
{
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
LONG ex_style = GetWindowLongW( hwnd, GWL_EXSTYLE );
|
||||
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
|
||||
LONG ex_style = GetWindowLongW( infoPtr->hwnd, GWL_EXSTYLE );
|
||||
WCHAR *text;
|
||||
ICONINFO iconInfo;
|
||||
BITMAP bm;
|
||||
|
@ -730,14 +722,14 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
|||
{
|
||||
HFONT hFont, hPrevFont = 0;
|
||||
|
||||
if (!(text = get_button_text( hwnd ))) goto empty_rect;
|
||||
if (!(text = get_button_text( infoPtr ))) goto empty_rect;
|
||||
if (!text[0])
|
||||
{
|
||||
heap_free( text );
|
||||
goto empty_rect;
|
||||
}
|
||||
|
||||
if ((hFont = get_button_font( hwnd ))) hPrevFont = SelectObject( hdc, hFont );
|
||||
if ((hFont = infoPtr->font)) hPrevFont = SelectObject( hdc, hFont );
|
||||
DrawTextW(hdc, text, -1, &r, dtStyle | DT_CALCRECT);
|
||||
if (hPrevFont) SelectObject( hdc, hPrevFont );
|
||||
heap_free( text );
|
||||
|
@ -745,7 +737,7 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
|||
}
|
||||
|
||||
case BS_ICON:
|
||||
if (!GetIconInfo((HICON)GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET ), &iconInfo))
|
||||
if (!GetIconInfo(infoPtr->u.icon, &iconInfo))
|
||||
goto empty_rect;
|
||||
|
||||
GetObjectW (iconInfo.hbmColor, sizeof(BITMAP), &bm);
|
||||
|
@ -758,7 +750,7 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
|||
break;
|
||||
|
||||
case BS_BITMAP:
|
||||
if (!GetObjectW( (HANDLE)GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET ), sizeof(BITMAP), &bm))
|
||||
if (!GetObjectW( infoPtr->u.bitmap, sizeof(BITMAP), &bm))
|
||||
goto empty_rect;
|
||||
|
||||
r.right = r.left + bm.bmWidth;
|
||||
|
@ -826,15 +818,15 @@ static BOOL CALLBACK BUTTON_DrawTextCallback(HDC hdc, LPARAM lp, WPARAM wp, int
|
|||
*
|
||||
* Common function for drawing button label.
|
||||
*/
|
||||
static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, const RECT *rc)
|
||||
static void BUTTON_DrawLabel(const BUTTON_INFO *infoPtr, HDC hdc, UINT dtFlags, const RECT *rc)
|
||||
{
|
||||
DRAWSTATEPROC lpOutputProc = NULL;
|
||||
LPARAM lp;
|
||||
WPARAM wp = 0;
|
||||
HBRUSH hbr = 0;
|
||||
UINT flags = IsWindowEnabled(hwnd) ? DSS_NORMAL : DSS_DISABLED;
|
||||
LONG state = get_button_state( hwnd );
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
UINT flags = IsWindowEnabled(infoPtr->hwnd) ? DSS_NORMAL : DSS_DISABLED;
|
||||
LONG state = infoPtr->state;
|
||||
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
|
||||
WCHAR *text = NULL;
|
||||
|
||||
/* FIXME: To draw disabled label in Win31 look-and-feel, we probably
|
||||
|
@ -853,19 +845,19 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, const RECT *rc)
|
|||
case BS_TEXT:
|
||||
/* DST_COMPLEX -- is 0 */
|
||||
lpOutputProc = BUTTON_DrawTextCallback;
|
||||
if (!(text = get_button_text( hwnd ))) return;
|
||||
if (!(text = get_button_text( infoPtr ))) return;
|
||||
lp = (LPARAM)text;
|
||||
wp = dtFlags;
|
||||
break;
|
||||
|
||||
case BS_ICON:
|
||||
flags |= DST_ICON;
|
||||
lp = GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET );
|
||||
lp = (LPARAM)infoPtr->u.icon;
|
||||
break;
|
||||
|
||||
case BS_BITMAP:
|
||||
flags |= DST_BITMAP;
|
||||
lp = GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET );
|
||||
lp = (LPARAM)infoPtr->u.bitmap;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -880,7 +872,7 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, const RECT *rc)
|
|||
/**********************************************************************
|
||||
* Push Button Functions
|
||||
*/
|
||||
static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
|
||||
static void PB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
|
||||
{
|
||||
RECT rc, r;
|
||||
UINT dtFlags, uState;
|
||||
|
@ -889,19 +881,19 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
INT oldBkMode;
|
||||
COLORREF oldTxtColor;
|
||||
HFONT hFont;
|
||||
LONG state = get_button_state( hwnd );
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
LONG state = infoPtr->state;
|
||||
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
|
||||
BOOL pushedState = (state & BST_PUSHED);
|
||||
HWND parent;
|
||||
HRGN hrgn;
|
||||
|
||||
GetClientRect( hwnd, &rc );
|
||||
GetClientRect( infoPtr->hwnd, &rc );
|
||||
|
||||
/* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */
|
||||
if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont );
|
||||
parent = GetParent(hwnd);
|
||||
if (!parent) parent = hwnd;
|
||||
SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)hwnd );
|
||||
if ((hFont = infoPtr->font)) SelectObject( hDC, hFont );
|
||||
parent = GetParent(infoPtr->hwnd);
|
||||
if (!parent) parent = infoPtr->hwnd;
|
||||
SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)infoPtr->hwnd );
|
||||
|
||||
hrgn = set_control_clipping( hDC, &rc );
|
||||
|
||||
|
@ -939,7 +931,7 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
|
||||
/* draw button label */
|
||||
r = rc;
|
||||
dtFlags = BUTTON_CalcLabelRect(hwnd, hDC, &r);
|
||||
dtFlags = BUTTON_CalcLabelRect(infoPtr, hDC, &r);
|
||||
|
||||
if (dtFlags == (UINT)-1L)
|
||||
goto cleanup;
|
||||
|
@ -949,7 +941,7 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
|
||||
oldTxtColor = SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
|
||||
|
||||
BUTTON_DrawLabel(hwnd, hDC, dtFlags, &r);
|
||||
BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &r);
|
||||
|
||||
SetTextColor( hDC, oldTxtColor );
|
||||
|
||||
|
@ -973,42 +965,40 @@ draw_focus:
|
|||
* Check Box & Radio Button Functions
|
||||
*/
|
||||
|
||||
static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
||||
static void CB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
|
||||
{
|
||||
RECT rbox, rtext, client;
|
||||
HBRUSH hBrush;
|
||||
int delta, text_offset, checkBoxWidth, checkBoxHeight;
|
||||
UINT dtFlags;
|
||||
HFONT hFont;
|
||||
LONG state = get_button_state( hwnd );
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
LONG ex_style = GetWindowLongW( hwnd, GWL_EXSTYLE );
|
||||
LONG state = infoPtr->state;
|
||||
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
|
||||
LONG ex_style = GetWindowLongW( infoPtr->hwnd, GWL_EXSTYLE );
|
||||
HWND parent;
|
||||
HRGN hrgn;
|
||||
|
||||
if (style & BS_PUSHLIKE)
|
||||
{
|
||||
PB_Paint( hwnd, hDC, action );
|
||||
PB_Paint( infoPtr, hDC, action );
|
||||
return;
|
||||
}
|
||||
|
||||
GetClientRect(hwnd, &client);
|
||||
GetClientRect(infoPtr->hwnd, &client);
|
||||
rbox = rtext = client;
|
||||
|
||||
checkBoxWidth = 12 * GetDeviceCaps( hDC, LOGPIXELSX ) / 96 + 1;
|
||||
checkBoxHeight = 12 * GetDeviceCaps( hDC, LOGPIXELSY ) / 96 + 1;
|
||||
|
||||
if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont );
|
||||
if ((hFont = infoPtr->font)) SelectObject( hDC, hFont );
|
||||
GetCharWidthW( hDC, '0', '0', &text_offset );
|
||||
text_offset /= 2;
|
||||
|
||||
parent = GetParent(hwnd);
|
||||
if (!parent) parent = hwnd;
|
||||
hBrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC,
|
||||
(WPARAM)hDC, (LPARAM)hwnd);
|
||||
parent = GetParent(infoPtr->hwnd);
|
||||
if (!parent) parent = infoPtr->hwnd;
|
||||
hBrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)infoPtr->hwnd);
|
||||
if (!hBrush) /* did the app forget to call defwindowproc ? */
|
||||
hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC,
|
||||
(WPARAM)hDC, (LPARAM)hwnd );
|
||||
hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)infoPtr->hwnd);
|
||||
hrgn = set_control_clipping( hDC, &client );
|
||||
|
||||
if (style & BS_LEFTTEXT || ex_style & WS_EX_RIGHT)
|
||||
|
@ -1028,7 +1018,7 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
|
||||
/* Draw label */
|
||||
client = rtext;
|
||||
dtFlags = BUTTON_CalcLabelRect(hwnd, hDC, &rtext);
|
||||
dtFlags = BUTTON_CalcLabelRect(infoPtr, hDC, &rtext);
|
||||
|
||||
/* Only adjust rbox when rtext is valid */
|
||||
if (dtFlags != (UINT)-1L)
|
||||
|
@ -1088,7 +1078,7 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
return;
|
||||
|
||||
if (action == ODA_DRAWENTIRE)
|
||||
BUTTON_DrawLabel(hwnd, hDC, dtFlags, &rtext);
|
||||
BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &rtext);
|
||||
|
||||
/* ... and focus */
|
||||
if (action == ODA_FOCUS || (state & BST_FOCUS))
|
||||
|
@ -1130,26 +1120,25 @@ static void BUTTON_CheckAutoRadioButton( HWND hwnd )
|
|||
* Group Box Functions
|
||||
*/
|
||||
|
||||
static void GB_Paint( HWND hwnd, HDC hDC, UINT action )
|
||||
static void GB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
|
||||
{
|
||||
RECT rc, rcFrame;
|
||||
HBRUSH hbr;
|
||||
HFONT hFont;
|
||||
UINT dtFlags;
|
||||
TEXTMETRICW tm;
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
|
||||
HWND parent;
|
||||
HRGN hrgn;
|
||||
|
||||
if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont );
|
||||
if ((hFont = infoPtr->font)) SelectObject( hDC, hFont );
|
||||
/* GroupBox acts like static control, so it sends CTLCOLORSTATIC */
|
||||
parent = GetParent(hwnd);
|
||||
if (!parent) parent = hwnd;
|
||||
hbr = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)hwnd);
|
||||
parent = GetParent(infoPtr->hwnd);
|
||||
if (!parent) parent = infoPtr->hwnd;
|
||||
hbr = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)infoPtr->hwnd);
|
||||
if (!hbr) /* did the app forget to call defwindowproc ? */
|
||||
hbr = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC,
|
||||
(WPARAM)hDC, (LPARAM)hwnd);
|
||||
GetClientRect( hwnd, &rc);
|
||||
hbr = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)infoPtr->hwnd);
|
||||
GetClientRect( infoPtr->hwnd, &rc);
|
||||
rcFrame = rc;
|
||||
hrgn = set_control_clipping( hDC, &rc );
|
||||
|
||||
|
@ -1158,7 +1147,7 @@ static void GB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
DrawEdge (hDC, &rcFrame, EDGE_ETCHED, BF_RECT | ((style & BS_FLAT) ? BF_FLAT : 0));
|
||||
|
||||
InflateRect(&rc, -7, 1);
|
||||
dtFlags = BUTTON_CalcLabelRect(hwnd, hDC, &rc);
|
||||
dtFlags = BUTTON_CalcLabelRect(infoPtr, hDC, &rc);
|
||||
|
||||
if (dtFlags != (UINT)-1)
|
||||
{
|
||||
|
@ -1172,7 +1161,7 @@ static void GB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
FillRect(hDC, &rc, hbr);
|
||||
rc.left++; rc.right--; rc.bottom--;
|
||||
|
||||
BUTTON_DrawLabel(hwnd, hDC, dtFlags, &rc);
|
||||
BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &rc);
|
||||
}
|
||||
SelectClipRgn( hDC, hrgn );
|
||||
if (hrgn) DeleteObject( hrgn );
|
||||
|
@ -1183,24 +1172,23 @@ static void GB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
* User Button Functions
|
||||
*/
|
||||
|
||||
static void UB_Paint( HWND hwnd, HDC hDC, UINT action )
|
||||
static void UB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
|
||||
{
|
||||
RECT rc;
|
||||
HBRUSH hBrush;
|
||||
HFONT hFont;
|
||||
LONG state = get_button_state( hwnd );
|
||||
LONG state = infoPtr->state;
|
||||
HWND parent;
|
||||
|
||||
GetClientRect( hwnd, &rc);
|
||||
GetClientRect( infoPtr->hwnd, &rc);
|
||||
|
||||
if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont );
|
||||
if ((hFont = infoPtr->font)) SelectObject( hDC, hFont );
|
||||
|
||||
parent = GetParent(hwnd);
|
||||
if (!parent) parent = hwnd;
|
||||
hBrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)hwnd);
|
||||
parent = GetParent(infoPtr->hwnd);
|
||||
if (!parent) parent = infoPtr->hwnd;
|
||||
hBrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)infoPtr->hwnd);
|
||||
if (!hBrush) /* did the app forget to call defwindowproc ? */
|
||||
hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORBTN,
|
||||
(WPARAM)hDC, (LPARAM)hwnd);
|
||||
hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)infoPtr->hwnd);
|
||||
|
||||
FillRect( hDC, &rc, hBrush );
|
||||
if (action == ODA_FOCUS || (state & BST_FOCUS))
|
||||
|
@ -1209,11 +1197,11 @@ static void UB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
switch (action)
|
||||
{
|
||||
case ODA_FOCUS:
|
||||
BUTTON_NOTIFY_PARENT( hwnd, (state & BST_FOCUS) ? BN_SETFOCUS : BN_KILLFOCUS );
|
||||
BUTTON_NOTIFY_PARENT( infoPtr->hwnd, (state & BST_FOCUS) ? BN_SETFOCUS : BN_KILLFOCUS );
|
||||
break;
|
||||
|
||||
case ODA_SELECT:
|
||||
BUTTON_NOTIFY_PARENT( hwnd, (state & BST_PUSHED) ? BN_HILITE : BN_UNHILITE );
|
||||
BUTTON_NOTIFY_PARENT( infoPtr->hwnd, (state & BST_PUSHED) ? BN_HILITE : BN_UNHILITE );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1226,11 +1214,11 @@ static void UB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
* Ownerdrawn Button Functions
|
||||
*/
|
||||
|
||||
static void OB_Paint( HWND hwnd, HDC hDC, UINT action )
|
||||
static void OB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
|
||||
{
|
||||
LONG state = get_button_state( hwnd );
|
||||
LONG state = infoPtr->state;
|
||||
DRAWITEMSTRUCT dis;
|
||||
LONG_PTR id = GetWindowLongPtrW( hwnd, GWLP_ID );
|
||||
LONG_PTR id = GetWindowLongPtrW( infoPtr->hwnd, GWLP_ID );
|
||||
HWND parent;
|
||||
HFONT hFont, hPrevFont = 0;
|
||||
HRGN hrgn;
|
||||
|
@ -1241,40 +1229,40 @@ static void OB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
dis.itemAction = action;
|
||||
dis.itemState = ((state & BST_FOCUS) ? ODS_FOCUS : 0) |
|
||||
((state & BST_PUSHED) ? ODS_SELECTED : 0) |
|
||||
(IsWindowEnabled(hwnd) ? 0: ODS_DISABLED);
|
||||
dis.hwndItem = hwnd;
|
||||
(IsWindowEnabled(infoPtr->hwnd) ? 0: ODS_DISABLED);
|
||||
dis.hwndItem = infoPtr->hwnd;
|
||||
dis.hDC = hDC;
|
||||
dis.itemData = 0;
|
||||
GetClientRect( hwnd, &dis.rcItem );
|
||||
GetClientRect( infoPtr->hwnd, &dis.rcItem );
|
||||
|
||||
if ((hFont = get_button_font( hwnd ))) hPrevFont = SelectObject( hDC, hFont );
|
||||
parent = GetParent(hwnd);
|
||||
if (!parent) parent = hwnd;
|
||||
SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)hwnd );
|
||||
if ((hFont = infoPtr->font)) hPrevFont = SelectObject( hDC, hFont );
|
||||
parent = GetParent(infoPtr->hwnd);
|
||||
if (!parent) parent = infoPtr->hwnd;
|
||||
SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)infoPtr->hwnd );
|
||||
|
||||
hrgn = set_control_clipping( hDC, &dis.rcItem );
|
||||
|
||||
SendMessageW( GetParent(hwnd), WM_DRAWITEM, id, (LPARAM)&dis );
|
||||
SendMessageW( GetParent(infoPtr->hwnd), WM_DRAWITEM, id, (LPARAM)&dis );
|
||||
if (hPrevFont) SelectObject(hDC, hPrevFont);
|
||||
SelectClipRgn( hDC, hrgn );
|
||||
if (hrgn) DeleteObject( hrgn );
|
||||
}
|
||||
|
||||
static void PB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused)
|
||||
static void PB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused)
|
||||
{
|
||||
static const int states[] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED, PBS_DEFAULTED };
|
||||
|
||||
RECT bgRect, textRect;
|
||||
HFONT font = get_button_font( hwnd );
|
||||
HFONT font = infoPtr->font;
|
||||
HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL;
|
||||
int state = states[ drawState ];
|
||||
WCHAR *text = get_button_text(hwnd);
|
||||
WCHAR *text = get_button_text(infoPtr);
|
||||
|
||||
GetClientRect(hwnd, &bgRect);
|
||||
GetClientRect(infoPtr->hwnd, &bgRect);
|
||||
GetThemeBackgroundContentRect(theme, hDC, BP_PUSHBUTTON, state, &bgRect, &textRect);
|
||||
|
||||
if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state))
|
||||
DrawThemeParentBackground(hwnd, hDC, NULL);
|
||||
DrawThemeParentBackground(infoPtr->hwnd, hDC, NULL);
|
||||
DrawThemeBackground(theme, hDC, BP_PUSHBUTTON, state, &bgRect, NULL);
|
||||
if (text)
|
||||
{
|
||||
|
@ -1300,7 +1288,7 @@ static void PB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawSta
|
|||
if (hPrevFont) SelectObject(hDC, hPrevFont);
|
||||
}
|
||||
|
||||
static void CB_ThemedPaint(HTHEME theme, HWND hwnd, 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 const int cb_states[3][5] =
|
||||
{
|
||||
|
@ -1318,14 +1306,14 @@ static void CB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawSta
|
|||
SIZE sz;
|
||||
RECT bgRect, textRect;
|
||||
HFONT font, hPrevFont = NULL;
|
||||
int checkState = get_button_state( hwnd ) & 3;
|
||||
DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
|
||||
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(hwnd);
|
||||
WCHAR *text = get_button_text(infoPtr);
|
||||
LOGFONTW lf;
|
||||
BOOL created_font = FALSE;
|
||||
|
||||
|
@ -1340,14 +1328,14 @@ static void CB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawSta
|
|||
created_font = TRUE;
|
||||
}
|
||||
} else {
|
||||
font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
|
||||
font = (HFONT)SendMessageW(infoPtr->hwnd, WM_GETFONT, 0, 0);
|
||||
hPrevFont = SelectObject(hDC, font);
|
||||
}
|
||||
|
||||
if (FAILED(GetThemePartSize(theme, hDC, part, state, NULL, TS_DRAW, &sz)))
|
||||
sz.cx = sz.cy = 13;
|
||||
|
||||
GetClientRect(hwnd, &bgRect);
|
||||
GetClientRect(infoPtr->hwnd, &bgRect);
|
||||
GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect);
|
||||
|
||||
if (dtFlags & DT_SINGLELINE) /* Center the checkbox / radio button to the text. */
|
||||
|
@ -1358,7 +1346,7 @@ static void CB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawSta
|
|||
bgRect.right = bgRect.left + sz.cx;
|
||||
textRect.left = bgRect.right + 6;
|
||||
|
||||
DrawThemeParentBackground(hwnd, hDC, NULL);
|
||||
DrawThemeParentBackground(infoPtr->hwnd, hDC, NULL);
|
||||
|
||||
DrawThemeBackground(theme, hDC, part, state, &bgRect, NULL);
|
||||
if (text)
|
||||
|
@ -1386,13 +1374,13 @@ static void CB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawSta
|
|||
if (hPrevFont) SelectObject(hDC, hPrevFont);
|
||||
}
|
||||
|
||||
static void GB_ThemedPaint(HTHEME theme, HWND hwnd, 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 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(hwnd);
|
||||
WCHAR *text = get_button_text(infoPtr);
|
||||
LOGFONTW lf;
|
||||
HFONT font, hPrevFont = NULL;
|
||||
BOOL created_font = FALSE;
|
||||
|
@ -1407,11 +1395,11 @@ static void GB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawSta
|
|||
created_font = TRUE;
|
||||
}
|
||||
} else {
|
||||
font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
|
||||
font = (HFONT)SendMessageW(infoPtr->hwnd, WM_GETFONT, 0, 0);
|
||||
hPrevFont = SelectObject(hDC, font);
|
||||
}
|
||||
|
||||
GetClientRect(hwnd, &bgRect);
|
||||
GetClientRect(infoPtr->hwnd, &bgRect);
|
||||
textRect = bgRect;
|
||||
|
||||
if (text)
|
||||
|
@ -1430,7 +1418,7 @@ static void GB_ThemedPaint(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawSta
|
|||
ExcludeClipRect(hDC, contentRect.left, contentRect.top, contentRect.right, contentRect.bottom);
|
||||
|
||||
if (IsThemeBackgroundPartiallyTransparent(theme, BP_GROUPBOX, state))
|
||||
DrawThemeParentBackground(hwnd, hDC, NULL);
|
||||
DrawThemeParentBackground(infoPtr->hwnd, hDC, NULL);
|
||||
DrawThemeBackground(theme, hDC, BP_GROUPBOX, state, &bgRect, NULL);
|
||||
|
||||
SelectClipRgn(hDC, NULL);
|
||||
|
@ -1454,7 +1442,7 @@ void BUTTON_Register(void)
|
|||
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC;
|
||||
wndClass.lpfnWndProc = BUTTON_WindowProc;
|
||||
wndClass.cbClsExtra = 0;
|
||||
wndClass.cbWndExtra = NB_EXTRA_BYTES;
|
||||
wndClass.cbWndExtra = sizeof(BUTTON_INFO *);
|
||||
wndClass.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
|
||||
wndClass.hbrBackground = NULL;
|
||||
wndClass.lpszClassName = WC_BUTTONW;
|
||||
|
|
|
@ -729,10 +729,14 @@ static void test_button_class(void)
|
|||
ret = GetClassInfoExA(NULL, WC_BUTTONA, &exA);
|
||||
ok(ret, "got %d\n", ret);
|
||||
ok(IS_WNDPROC_HANDLE(exA.lpfnWndProc), "got %p\n", exA.lpfnWndProc);
|
||||
ok(exA.cbClsExtra == 0, "Unexpected class bytes %d.\n", exA.cbClsExtra);
|
||||
ok(exA.cbWndExtra == sizeof(void *), "Unexpected window bytes %d.\n", exA.cbWndExtra);
|
||||
|
||||
ret = GetClassInfoExW(NULL, WC_BUTTONW, &exW);
|
||||
ok(ret, "got %d\n", ret);
|
||||
ok(!IS_WNDPROC_HANDLE(exW.lpfnWndProc), "got %p\n", exW.lpfnWndProc);
|
||||
ok(exW.cbClsExtra == 0, "Unexpected class bytes %d.\n", exW.cbClsExtra);
|
||||
ok(exW.cbWndExtra == sizeof(void *), "Unexpected window bytes %d.\n", exW.cbWndExtra);
|
||||
|
||||
/* check that versioned class is also accessible */
|
||||
nameW = get_versioned_classname(WC_BUTTONW);
|
||||
|
|
Loading…
Reference in New Issue