comctl32/button: Implement NM_CUSTOMDRAW for Push Buttons.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=10531 Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
74b17a353a
commit
4b85740ebf
|
@ -237,6 +237,28 @@ static inline WCHAR *get_button_text( const BUTTON_INFO *infoPtr )
|
|||
return buffer;
|
||||
}
|
||||
|
||||
static void init_custom_draw(NMCUSTOMDRAW *nmcd, const BUTTON_INFO *infoPtr, HDC hdc, const RECT *rc)
|
||||
{
|
||||
nmcd->hdr.hwndFrom = infoPtr->hwnd;
|
||||
nmcd->hdr.idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);
|
||||
nmcd->hdr.code = NM_CUSTOMDRAW;
|
||||
nmcd->hdc = hdc;
|
||||
nmcd->rc = *rc;
|
||||
nmcd->dwDrawStage = CDDS_PREERASE;
|
||||
nmcd->dwItemSpec = 0;
|
||||
nmcd->lItemlParam = 0;
|
||||
nmcd->uItemState = IsWindowEnabled(infoPtr->hwnd) ? 0 : CDIS_DISABLED;
|
||||
if (infoPtr->state & BST_PUSHED) nmcd->uItemState |= CDIS_SELECTED;
|
||||
if (infoPtr->state & BST_FOCUS) nmcd->uItemState |= CDIS_FOCUS;
|
||||
if (infoPtr->state & BST_HOT) nmcd->uItemState |= CDIS_HOT;
|
||||
if (infoPtr->state & BST_INDETERMINATE)
|
||||
nmcd->uItemState |= CDIS_INDETERMINATE;
|
||||
|
||||
/* Windows doesn't seem to send CDIS_CHECKED (it fails the tests) */
|
||||
/* CDIS_SHOWKEYBOARDCUES is misleading, as the meaning is reversed */
|
||||
/* FIXME: Handle it properly when we support keyboard cues? */
|
||||
}
|
||||
|
||||
HRGN set_control_clipping( HDC hdc, const RECT *rect )
|
||||
{
|
||||
RECT rc = *rect;
|
||||
|
@ -1476,7 +1498,9 @@ static void PB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
|
|||
HBRUSH hOldBrush;
|
||||
INT oldBkMode;
|
||||
COLORREF oldTxtColor;
|
||||
LRESULT cdrf;
|
||||
HFONT hFont;
|
||||
NMCUSTOMDRAW nmcd;
|
||||
LONG state = infoPtr->state;
|
||||
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
|
||||
BOOL pushedState = (state & BST_PUSHED);
|
||||
|
@ -1498,6 +1522,12 @@ static void PB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
|
|||
hOldBrush = SelectObject(hDC,GetSysColorBrush(COLOR_BTNFACE));
|
||||
oldBkMode = SetBkMode(hDC, TRANSPARENT);
|
||||
|
||||
init_custom_draw(&nmcd, infoPtr, hDC, &rc);
|
||||
|
||||
/* Send erase notifications */
|
||||
cdrf = SendMessageW(parent, WM_NOTIFY, nmcd.hdr.idFrom, (LPARAM)&nmcd);
|
||||
if (cdrf & CDRF_SKIPDEFAULT) goto cleanup;
|
||||
|
||||
if (get_button_type(style) == BS_DEFPUSHBUTTON)
|
||||
{
|
||||
if (action != ODA_FOCUS)
|
||||
|
@ -1505,44 +1535,65 @@ static void PB_Paint( const BUTTON_INFO *infoPtr, 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)
|
||||
uState |= DFCS_MONO;
|
||||
else if (pushedState)
|
||||
/* Skip the frame drawing if only focus has changed */
|
||||
if (action != ODA_FOCUS)
|
||||
{
|
||||
if (get_button_type(style) == BS_DEFPUSHBUTTON )
|
||||
uState |= DFCS_FLAT;
|
||||
else
|
||||
uState |= DFCS_PUSHED;
|
||||
uState = DFCS_BUTTONPUSH;
|
||||
|
||||
if (style & BS_FLAT)
|
||||
uState |= DFCS_MONO;
|
||||
else if (pushedState)
|
||||
{
|
||||
if (get_button_type(style) == BS_DEFPUSHBUTTON )
|
||||
uState |= DFCS_FLAT;
|
||||
else
|
||||
uState |= DFCS_PUSHED;
|
||||
}
|
||||
|
||||
if (state & (BST_CHECKED | BST_INDETERMINATE))
|
||||
uState |= DFCS_CHECKED;
|
||||
|
||||
DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
|
||||
}
|
||||
|
||||
if (state & (BST_CHECKED | BST_INDETERMINATE))
|
||||
uState |= DFCS_CHECKED;
|
||||
if (cdrf & CDRF_NOTIFYPOSTERASE)
|
||||
{
|
||||
nmcd.dwDrawStage = CDDS_POSTERASE;
|
||||
SendMessageW(parent, WM_NOTIFY, nmcd.hdr.idFrom, (LPARAM)&nmcd);
|
||||
}
|
||||
|
||||
DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
|
||||
/* Send paint notifications */
|
||||
nmcd.dwDrawStage = CDDS_PREPAINT;
|
||||
cdrf = SendMessageW(parent, WM_NOTIFY, nmcd.hdr.idFrom, (LPARAM)&nmcd);
|
||||
if (cdrf & CDRF_SKIPDEFAULT) goto cleanup;
|
||||
|
||||
/* draw button label */
|
||||
labelRect = rc;
|
||||
/* Shrink label rect at all sides by 2 so that the content won't touch the surrounding frame */
|
||||
InflateRect(&labelRect, -2, -2);
|
||||
dtFlags = BUTTON_CalcLayoutRects(infoPtr, hDC, &labelRect, &imageRect, &textRect);
|
||||
if (!(cdrf & CDRF_DOERASE) && action != ODA_FOCUS)
|
||||
{
|
||||
/* draw button label */
|
||||
labelRect = rc;
|
||||
/* Shrink label rect at all sides by 2 so that the content won't touch the surrounding frame */
|
||||
InflateRect(&labelRect, -2, -2);
|
||||
dtFlags = BUTTON_CalcLayoutRects(infoPtr, hDC, &labelRect, &imageRect, &textRect);
|
||||
|
||||
if (dtFlags == (UINT)-1L)
|
||||
goto cleanup;
|
||||
if (dtFlags != (UINT)-1L)
|
||||
{
|
||||
if (pushedState) OffsetRect(&labelRect, 1, 1);
|
||||
|
||||
if (pushedState) OffsetRect(&labelRect, 1, 1);
|
||||
oldTxtColor = SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
|
||||
|
||||
oldTxtColor = SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
|
||||
BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &imageRect, &textRect);
|
||||
|
||||
BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &imageRect, &textRect);
|
||||
SetTextColor( hDC, oldTxtColor );
|
||||
}
|
||||
}
|
||||
|
||||
SetTextColor( hDC, oldTxtColor );
|
||||
if (cdrf & CDRF_NOTIFYPOSTPAINT)
|
||||
{
|
||||
nmcd.dwDrawStage = CDDS_POSTPAINT;
|
||||
SendMessageW(parent, WM_NOTIFY, nmcd.hdr.idFrom, (LPARAM)&nmcd);
|
||||
}
|
||||
if ((cdrf & CDRF_SKIPPOSTPAINT) || dtFlags == (UINT)-1L) goto cleanup;
|
||||
|
||||
draw_focus:
|
||||
if (action == ODA_FOCUS || (state & BST_FOCUS))
|
||||
{
|
||||
InflateRect( &rc, -2, -2 );
|
||||
|
|
Loading…
Reference in New Issue