[PATCH 3/7] comctl32/button: Support displaying both image and text.
Zhiyi Zhang
zzhang at codeweavers.com
Wed Sep 5 09:57:39 CDT 2018
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45727
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/comctl32/button.c | 421 +++++++++++++++++++++++++++++------------
1 file changed, 295 insertions(+), 126 deletions(-)
diff --git a/dlls/comctl32/button.c b/dlls/comctl32/button.c
index 6f9bc39de5..653586a748 100644
--- a/dlls/comctl32/button.c
+++ b/dlls/comctl32/button.c
@@ -98,7 +98,7 @@ typedef struct _BUTTON_INFO
} u;
} BUTTON_INFO;
-static UINT BUTTON_CalcLabelRect( const BUTTON_INFO *infoPtr, HDC hdc, RECT *rc );
+static UINT BUTTON_CalcLayoutRects( const BUTTON_INFO *infoPtr, HDC hdc, RECT *labelRc, RECT *imageRc, RECT *textRc );
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 );
@@ -615,7 +615,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(infoPtr, hdc, &rc);
+ BUTTON_CalcLayoutRects(infoPtr, hdc, &rc, NULL, NULL);
/* Clip by client rect bounds */
if (rc.right > client.right) rc.right = client.right;
if (rc.bottom > client.bottom) rc.bottom = client.bottom;
@@ -855,95 +855,257 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
return 0;
}
+/* If maxWidth is zero, rectangle width is unlimited */
+static RECT BUTTON_GetTextRect(const BUTTON_INFO *infoPtr, HDC hdc, const WCHAR *text, LONG maxWidth)
+{
+ LONG style = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
+ LONG exStyle = GetWindowLongW(infoPtr->hwnd, GWL_EXSTYLE);
+ UINT dtStyle = BUTTON_BStoDT(style, exStyle);
+ HFONT hPrevFont;
+ RECT rect = {0};
+
+ rect.right = maxWidth;
+ hPrevFont = SelectObject(hdc, infoPtr->font);
+ /* Calculate height without DT_VCENTER and DT_BOTTOM to get the correct height */
+ DrawTextW(hdc, text, -1, &rect, (dtStyle & ~(DT_VCENTER | DT_BOTTOM)) | DT_CALCRECT);
+ if (hPrevFont) SelectObject(hdc, hPrevFont);
+
+ return rect;
+}
+
+static BOOL show_image_only(const BUTTON_INFO *infoPtr)
+{
+ LONG style = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
+ return (style & (BS_ICON | BS_BITMAP)) && infoPtr->u.image;
+}
+
+static BOOL show_image_and_text(const BUTTON_INFO *infoPtr)
+{
+ LONG style = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
+ UINT type = get_button_type(style);
+ return !(style & (BS_ICON | BS_BITMAP)) && infoPtr->u.image
+ && (type == BS_PUSHBUTTON || type == BS_DEFPUSHBUTTON || type == BS_USERBUTTON || type == BS_SPLITBUTTON
+ || type == BS_DEFSPLITBUTTON || type == BS_COMMANDLINK || type == BS_DEFCOMMANDLINK);
+}
+
+static BOOL show_image(const BUTTON_INFO *infoPtr)
+{
+ return show_image_only(infoPtr) || show_image_and_text(infoPtr);
+}
+
+/* Get a bounding rectangle that is large enough to contain a image and a text side by side.
+ * Note: (left,top) of the result rectangle may not be (0,0), offset it by yourself if needed */
+static RECT BUTTON_GetBoundingLabelRect(LONG style, const RECT *textRect, const RECT *imageRect)
+{
+ RECT labelRect;
+ RECT rect = *imageRect;
+ INT textWidth = textRect->right - textRect->left;
+ INT textHeight = textRect->bottom - textRect->top;
+ INT imageWidth = imageRect->right - imageRect->left;
+ INT imageHeight = imageRect->bottom - imageRect->top;
+
+ if ((style & BS_CENTER) == BS_RIGHT)
+ OffsetRect(&rect, textWidth, 0);
+ else if ((style & BS_CENTER) == BS_LEFT)
+ OffsetRect(&rect, -imageWidth, 0);
+ else if ((style & BS_VCENTER) == BS_BOTTOM)
+ OffsetRect(&rect, 0, textHeight);
+ else if ((style & BS_VCENTER) == BS_TOP)
+ OffsetRect(&rect, 0, -imageHeight);
+ else
+ OffsetRect(&rect, -imageWidth, 0);
+
+ UnionRect(&labelRect, textRect, &rect);
+ return labelRect;
+}
+
+/* Position a rectangle inside a bounding rectangle according to button alignment flags */
+static void BUTTON_PositionRect(LONG style, const RECT *outerRect, RECT *innerRect, const RECT *margin)
+{
+ INT width = innerRect->right - innerRect->left;
+ INT height = innerRect->bottom - innerRect->top;
+
+ if ((style & WS_EX_RIGHT) && !(style & BS_CENTER)) style |= BS_CENTER;
+
+ if (!(style & BS_CENTER))
+ {
+ /* Push button's text is centered by default, all other types have left aligned text */
+ if (get_button_type(style) <= BS_DEFPUSHBUTTON)
+ style |= BS_CENTER;
+ else
+ style |= BS_LEFT;
+ }
+
+ if (!(style & BS_VCENTER))
+ {
+ /* Group box's text is top aligned by default */
+ if (get_button_type(style) == BS_GROUPBOX)
+ style |= BS_TOP;
+ }
+
+ switch (style & BS_CENTER)
+ {
+ case BS_CENTER:
+ innerRect->left = outerRect->left + (outerRect->right - outerRect->left - width) / 2;
+ innerRect->right = innerRect->left + width;
+ break;
+ case BS_RIGHT:
+ innerRect->right = outerRect->right - margin->right;
+ innerRect->left = innerRect->right - width;
+ break;
+ case BS_LEFT:
+ default:
+ innerRect->left = outerRect->left + margin->left;
+ innerRect->right = innerRect->left + width;
+ break;
+ }
+
+ switch (style & BS_VCENTER)
+ {
+ case BS_TOP:
+ innerRect->top = outerRect->top + margin->top;
+ innerRect->bottom = innerRect->top + height;
+ break;
+ case BS_BOTTOM:
+ innerRect->bottom = outerRect->bottom - margin->bottom;
+ innerRect->top = innerRect->bottom - height;
+ break;
+ case BS_VCENTER:
+ default:
+ innerRect->top = outerRect->top + (outerRect->bottom - outerRect->top - height) / 2;
+ innerRect->bottom = innerRect->top + height;
+ break;
+ }
+}
+
+static SIZE BUTTON_GetImageSize(const BUTTON_INFO *infoPtr)
+{
+ ICONINFO iconInfo;
+ BITMAP bm = {0};
+ SIZE size = {0};
+
+ if (infoPtr->u.image)
+ {
+ if (infoPtr->image_type == IMAGE_ICON)
+ {
+ GetIconInfo(infoPtr->u.icon, &iconInfo);
+ GetObjectW(iconInfo.hbmColor, sizeof(bm), &bm);
+ DeleteObject(iconInfo.hbmColor);
+ DeleteObject(iconInfo.hbmMask);
+ }
+ else if (infoPtr->image_type == IMAGE_BITMAP)
+ GetObjectW(infoPtr->u.bitmap, sizeof(bm), &bm);
+
+ size.cx = bm.bmWidth;
+ size.cy = bm.bmHeight;
+ }
+
+ return size;
+}
+
/**********************************************************************
- * BUTTON_CalcLabelRect
+ * BUTTON_CalcLayoutRects
*
- * Calculates label's rectangle depending on button style.
+ * Calculates the rectangles of the button label(image and text) and its parts depending on a button's style.
*
* Returns flags to be passed to DrawText.
* Calculated rectangle doesn't take into account button state
* (pushed, etc.). If there is nothing to draw (no text/image) output
* rectangle is empty, and return value is (UINT)-1.
+ *
+ * PARAMS:
+ * infoPtr [I] Button pointer
+ * hdc [I] Handle to device context to draw to
+ * labelRc [I/O] Input the rect the label to be positioned in, and output the label rect
+ * imageRc [O] Optional, output the image rect
+ * textRc [O] Optional, output the text rect
*/
-static UINT BUTTON_CalcLabelRect(const BUTTON_INFO *infoPtr, HDC hdc, RECT *rc)
+static UINT BUTTON_CalcLayoutRects(const BUTTON_INFO *infoPtr, HDC hdc, RECT *labelRc, RECT *imageRc, RECT *textRc)
{
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
LONG ex_style = GetWindowLongW( infoPtr->hwnd, GWL_EXSTYLE );
WCHAR *text = get_button_text(infoPtr);
- ICONINFO iconInfo;
- BITMAP bm = { 0 };
- UINT dtStyle = BUTTON_BStoDT( style, ex_style );
- RECT r = *rc;
- INT n;
+ SIZE imageSize = BUTTON_GetImageSize(infoPtr);
+ UINT dtStyle = BUTTON_BStoDT(style, ex_style);
+ RECT labelRect, imageRect, textRect;
+ RECT emptyMargin = {0}, oneMargin = {1, 1, 1, 1};
+ LONG maxTextWidth;
/* Calculate label rectangle according to label type */
- /* FIXME: Doesn't support showing both image and text yet */
- if (infoPtr->u.image)
- {
- if (infoPtr->image_type == IMAGE_ICON)
- {
- GetIconInfo(infoPtr->u.icon, &iconInfo);
- GetObjectW(iconInfo.hbmColor, sizeof(bm), &bm);
- DeleteObject(iconInfo.hbmColor);
- DeleteObject(iconInfo.hbmMask);
- }
- else if (infoPtr->image_type == IMAGE_BITMAP)
- {
- GetObjectW(infoPtr->u.bitmap, sizeof(bm), &bm);
- }
-
- r.right = r.left + bm.bmWidth;
- r.bottom = r.top + bm.bmHeight;
- }
- else if (text && text[0])
+ if ((imageSize.cx == 0 && imageSize.cy == 0) && (text == NULL || text[0] == '\0'))
{
- HFONT hFont, hPrevFont = 0;
-
- if ((hFont = infoPtr->font)) hPrevFont = SelectObject(hdc, hFont);
- DrawTextW(hdc, text, -1, &r, dtStyle | DT_CALCRECT);
- if (hPrevFont) SelectObject(hdc, hPrevFont);
- }
-
- if ((infoPtr->u.image && bm.bmWidth == 0 && bm.bmHeight == 0)
- || (text == NULL || text[0] == '\0'))
- {
- rc->right = r.left;
- rc->bottom = r.top;
+ SetRectEmpty(labelRc);
+ SetRectEmpty(imageRc);
+ SetRectEmpty(textRc);
heap_free(text);
return (UINT)-1;
}
- heap_free(text);
- /* Position label inside bounding rectangle according to
- * alignment flags. (calculated rect is always left-top aligned).
- * If label is aligned to any side - shift label in opposite
- * direction to leave extra space for focus rectangle.
- */
- switch (dtStyle & (DT_CENTER|DT_RIGHT))
+ SetRect(&imageRect, 0, 0, imageSize.cx, imageSize.cy);
+
+ /* Show image only */
+ if (show_image_only(infoPtr))
{
- case DT_LEFT: r.left++; r.right++; break;
- case DT_CENTER: n = r.right - r.left;
- r.left = rc->left + ((rc->right - rc->left) - n) / 2;
- r.right = r.left + n; break;
- case DT_RIGHT: n = r.right - r.left;
- r.right = rc->right - 1;
- r.left = r.right - n;
- break;
+ BUTTON_PositionRect(style, labelRc, &imageRect,
+ infoPtr->imagelist.himl ? &infoPtr->imagelist.margin : &emptyMargin);
+ labelRect = imageRect;
+ SetRectEmpty(&textRect);
}
-
- switch (dtStyle & (DT_VCENTER|DT_BOTTOM))
+ else
{
- case DT_TOP: r.top++; r.bottom++; break;
- case DT_VCENTER: n = r.bottom - r.top;
- r.top = rc->top + ((rc->bottom - rc->top) - n) / 2;
- r.bottom = r.top + n; break;
- case DT_BOTTOM: n = r.bottom - r.top;
- r.bottom = rc->bottom - 1;
- r.top = r.bottom - n;
- break;
+ /* Get text rect */
+ maxTextWidth = labelRc->right - labelRc->left;
+ textRect = BUTTON_GetTextRect(infoPtr, hdc, text, maxTextWidth);
+ heap_free(text);
+
+ /* Show image and text */
+ if (show_image_and_text(infoPtr))
+ {
+ RECT boundingLabelRect, boundingImageRect, boundingTextRect;
+
+ /* Get label rect */
+ /* Get a label bounding rect to position the label in the user specified label rect because text and
+ * image need to align together. */
+ boundingLabelRect = BUTTON_GetBoundingLabelRect(style, &textRect, &imageRect);
+ BUTTON_PositionRect(style, labelRc, &boundingLabelRect, &emptyMargin);
+ labelRect = boundingLabelRect;
+
+ /* Get image rect */
+ /* Split the label rect to two halves as two bounding rects for image and text */
+ boundingImageRect = labelRect;
+ if ((style & BS_CENTER) == BS_RIGHT)
+ boundingImageRect.left = boundingImageRect.right - imageSize.cx;
+ else if ((style & BS_CENTER) == BS_LEFT)
+ boundingImageRect.right = boundingImageRect.left + imageSize.cx;
+ else if ((style & BS_VCENTER) == BS_BOTTOM)
+ boundingImageRect.top = boundingImageRect.bottom - imageSize.cy;
+ else if ((style & BS_VCENTER) == BS_TOP)
+ boundingImageRect.bottom = boundingImageRect.top + imageSize.cy;
+ else
+ boundingImageRect.right = boundingImageRect.left + imageSize.cx;
+ BUTTON_PositionRect(style, &boundingImageRect, &imageRect, &emptyMargin);
+
+ /* Get text rect */
+ SubtractRect(&boundingTextRect, &labelRect, &boundingImageRect);
+ BUTTON_PositionRect(style, &boundingTextRect, &textRect, &oneMargin);
+ }
+ /* Show text only */
+ else
+ {
+ if (get_button_type(style) != BS_GROUPBOX)
+ BUTTON_PositionRect(style, labelRc, &textRect, &oneMargin);
+ else
+ /* GroupBox is always top aligned */
+ BUTTON_PositionRect((style & ~BS_VCENTER) | BS_TOP, labelRc, &textRect, &oneMargin);
+ labelRect = textRect;
+ SetRectEmpty(&imageRect);
+ }
}
- *rc = r;
+ CopyRect(labelRc, &labelRect);
+ CopyRect(imageRc, &imageRect);
+ CopyRect(textRc, &textRect);
+
return dtStyle;
}
@@ -962,19 +1124,25 @@ static BOOL CALLBACK BUTTON_DrawTextCallback(HDC hdc, LPARAM lp, WPARAM wp, int
return TRUE;
}
-
/**********************************************************************
* BUTTON_DrawLabel
*
* Common function for drawing button label.
+ *
+ * FIXME:
+ * 1. When BS_SINGLELINE is specified and text contains '\t', '\n' or '\r' in the middle, they are rendered as
+ * squares now whereas they should be ignored.
+ * 2. When BS_MULTILINE is specified and text contains space in the middle, the space mistakenly be rendered as newline.
*/
-static void BUTTON_DrawLabel(const BUTTON_INFO *infoPtr, HDC hdc, UINT dtFlags, const RECT *rc)
+static void BUTTON_DrawLabel(const BUTTON_INFO *infoPtr, HDC hdc, UINT dtFlags, const RECT *imageRect,
+ const RECT *textRect)
{
DRAWSTATEPROC lpOutputProc = NULL;
LPARAM lp;
WPARAM wp = 0;
HBRUSH hbr = 0;
UINT flags = IsWindowEnabled(infoPtr->hwnd) ? DSS_NORMAL : DSS_DISABLED;
+ UINT imageFlags;
LONG state = infoPtr->state;
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
WCHAR *text = NULL;
@@ -990,35 +1158,34 @@ static void BUTTON_DrawLabel(const BUTTON_INFO *infoPtr, HDC hdc, UINT dtFlags,
flags |= DSS_MONO;
}
- /* FIXME: Support drawing label with both image and text */
- if (infoPtr->u.image != 0)
+ switch (infoPtr->image_type)
{
- switch (infoPtr->image_type)
- {
- case IMAGE_ICON:
- flags |= DST_ICON;
- lp = (LPARAM)infoPtr->u.icon;
- break;
- case IMAGE_BITMAP:
- flags |= DST_BITMAP;
- lp = (LPARAM)infoPtr->u.bitmap;
- break;
- default:
- return;
- }
- }
- else
- {
- /* DST_COMPLEX -- is 0 */
- lpOutputProc = BUTTON_DrawTextCallback;
- if (!(text = get_button_text(infoPtr))) return;
- lp = (LPARAM)text;
- wp = dtFlags;
+ case IMAGE_ICON:
+ imageFlags = flags | DST_ICON;
+ lp = (LPARAM)infoPtr->u.icon;
+ break;
+ case IMAGE_BITMAP:
+ imageFlags = flags | DST_BITMAP;
+ lp = (LPARAM)infoPtr->u.bitmap;
+ break;
+ default:
+ return;
}
- DrawStateW(hdc, hbr, lpOutputProc, lp, wp, rc->left, rc->top,
- rc->right - rc->left, rc->bottom - rc->top, flags);
- heap_free( text );
+ if (show_image(infoPtr))
+ DrawStateW(hdc, hbr, lpOutputProc, lp, wp, imageRect->left, imageRect->top,
+ imageRect->right - imageRect->left, imageRect->bottom - imageRect->top, imageFlags);
+
+ if (show_image_only(infoPtr)) return;
+
+ /* DST_COMPLEX -- is 0 */
+ lpOutputProc = BUTTON_DrawTextCallback;
+ if (!(text = get_button_text(infoPtr))) return;
+ lp = (LPARAM)text;
+ wp = dtFlags;
+ DrawStateW(hdc, hbr, lpOutputProc, lp, wp, textRect->left, textRect->top, textRect->right - textRect->left,
+ textRect->bottom - textRect->top, flags);
+ heap_free(text);
}
/**********************************************************************
@@ -1026,7 +1193,7 @@ static void BUTTON_DrawLabel(const BUTTON_INFO *infoPtr, HDC hdc, UINT dtFlags,
*/
static void PB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
{
- RECT rc, r;
+ RECT rc, labelRect, imageRect, textRect;
UINT dtFlags, uState;
HPEN hOldPen, hpen;
HBRUSH hOldBrush;
@@ -1082,18 +1249,17 @@ static void PB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
/* draw button label */
- r = rc;
- dtFlags = BUTTON_CalcLabelRect(infoPtr, hDC, &r);
+ labelRect = rc;
+ dtFlags = BUTTON_CalcLayoutRects(infoPtr, hDC, &labelRect, &imageRect, &textRect);
if (dtFlags == (UINT)-1L)
goto cleanup;
- if (pushedState)
- OffsetRect(&r, 1, 1);
+ if (pushedState) OffsetRect(&labelRect, 1, 1);
oldTxtColor = SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
- BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &r);
+ BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &imageRect, &textRect);
SetTextColor( hDC, oldTxtColor );
@@ -1119,7 +1285,7 @@ draw_focus:
static void CB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
{
- RECT rbox, rtext, client;
+ RECT rbox, labelRect, imageRect, textRect, client;
HBRUSH hBrush;
int delta, text_offset, checkBoxWidth, checkBoxHeight;
UINT dtFlags;
@@ -1137,7 +1303,7 @@ static void CB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
}
GetClientRect(infoPtr->hwnd, &client);
- rbox = rtext = client;
+ rbox = labelRect = client;
checkBoxWidth = 12 * GetDpiForWindow( infoPtr->hwnd ) / 96 + 1;
checkBoxHeight = 12 * GetDpiForWindow( infoPtr->hwnd ) / 96 + 1;
@@ -1155,12 +1321,12 @@ static void CB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
if (style & BS_LEFTTEXT || ex_style & WS_EX_RIGHT)
{
- rtext.right -= checkBoxWidth + text_offset;
+ labelRect.right -= checkBoxWidth + text_offset;
rbox.left = rbox.right - checkBoxWidth;
}
else
{
- rtext.left += checkBoxWidth + text_offset;
+ labelRect.left += checkBoxWidth + text_offset;
rbox.right = checkBoxWidth;
}
@@ -1169,14 +1335,14 @@ static void CB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
if (action == ODA_DRAWENTIRE) FillRect( hDC, &client, hBrush );
/* Draw label */
- client = rtext;
- dtFlags = BUTTON_CalcLabelRect(infoPtr, hDC, &rtext);
+ client = labelRect;
+ dtFlags = BUTTON_CalcLayoutRects(infoPtr, hDC, &labelRect, &imageRect, &textRect);
/* Only adjust rbox when rtext is valid */
if (dtFlags != (UINT)-1L)
{
- rbox.top = rtext.top;
- rbox.bottom = rtext.bottom;
+ rbox.top = labelRect.top;
+ rbox.bottom = labelRect.bottom;
}
/* Draw the check-box bitmap */
@@ -1229,16 +1395,15 @@ static void CB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
if (dtFlags == (UINT)-1L) /* Noting to draw */
return;
- if (action == ODA_DRAWENTIRE)
- BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &rtext);
+ if (action == ODA_DRAWENTIRE) BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &imageRect, &textRect);
/* ... and focus */
if (action == ODA_FOCUS || (state & BST_FOCUS))
{
- rtext.left--;
- rtext.right++;
- IntersectRect(&rtext, &rtext, &client);
- DrawFocusRect( hDC, &rtext );
+ labelRect.left--;
+ labelRect.right++;
+ IntersectRect(&labelRect, &labelRect, &client);
+ DrawFocusRect(hDC, &labelRect);
}
SelectClipRgn( hDC, hrgn );
if (hrgn) DeleteObject( hrgn );
@@ -1274,7 +1439,7 @@ static void BUTTON_CheckAutoRadioButton( HWND hwnd )
static void GB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
{
- RECT rc, rcFrame;
+ RECT labelRect, imageRect, textRect, rcFrame;
HBRUSH hbr;
HFONT hFont;
UINT dtFlags;
@@ -1290,16 +1455,16 @@ static void GB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
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)infoPtr->hwnd);
- GetClientRect( infoPtr->hwnd, &rc);
- rcFrame = rc;
- hrgn = set_control_clipping( hDC, &rc );
+ GetClientRect(infoPtr->hwnd, &labelRect);
+ rcFrame = labelRect;
+ hrgn = set_control_clipping(hDC, &labelRect);
GetTextMetricsW (hDC, &tm);
rcFrame.top += (tm.tmHeight / 2) - 1;
DrawEdge (hDC, &rcFrame, EDGE_ETCHED, BF_RECT | ((style & BS_FLAT) ? BF_FLAT : 0));
- InflateRect(&rc, -7, 1);
- dtFlags = BUTTON_CalcLabelRect(infoPtr, hDC, &rc);
+ InflateRect(&labelRect, -7, 1);
+ dtFlags = BUTTON_CalcLayoutRects(infoPtr, hDC, &labelRect, &imageRect, &textRect);
if (dtFlags != (UINT)-1)
{
@@ -1309,11 +1474,15 @@ static void GB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action )
*/
/* There is 1-pixel margin at the left, right, and bottom */
- rc.left--; rc.right++; rc.bottom++;
- FillRect(hDC, &rc, hbr);
- rc.left++; rc.right--; rc.bottom--;
-
- BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &rc);
+ labelRect.left--;
+ labelRect.right++;
+ labelRect.bottom++;
+ FillRect(hDC, &labelRect, hbr);
+ labelRect.left++;
+ labelRect.right--;
+ labelRect.bottom--;
+
+ BUTTON_DrawLabel(infoPtr, hDC, dtFlags, &imageRect, &textRect);
}
SelectClipRgn( hDC, hrgn );
if (hrgn) DeleteObject( hrgn );
--
2.18.0
More information about the wine-devel
mailing list