comctl32/button: Remove style checking when handling BM_SETIMAGE.

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2018-04-03 09:10:57 +03:00 committed by Alexandre Julliard
parent 66aaaed339
commit 05d4e4a23b
2 changed files with 294 additions and 79 deletions

View File

@ -96,6 +96,7 @@ typedef struct _BUTTON_INFO
HFONT font;
WCHAR *note;
INT note_length;
DWORD image_type; /* IMAGE_BITMAP or IMAGE_ICON */
union
{
HICON icon;
@ -718,18 +719,7 @@ static LRESULT CALLBACK BUTTON_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
break;
case BM_SETIMAGE:
/* Check that image format matches button style */
switch (style & (BS_BITMAP|BS_ICON))
{
case BS_BITMAP:
if (wParam != IMAGE_BITMAP) return 0;
break;
case BS_ICON:
if (wParam != IMAGE_ICON) return 0;
break;
default:
return 0;
}
infoPtr->image_type = (DWORD)wParam;
oldHbitmap = infoPtr->u.image;
infoPtr->u.image = (HANDLE)lParam;
InvalidateRect( hWnd, NULL, FALSE );
@ -802,61 +792,50 @@ static UINT BUTTON_CalcLabelRect(const BUTTON_INFO *infoPtr, HDC hdc, RECT *rc)
{
LONG style = GetWindowLongW( infoPtr->hwnd, GWL_STYLE );
LONG ex_style = GetWindowLongW( infoPtr->hwnd, GWL_EXSTYLE );
WCHAR *text;
WCHAR *text = get_button_text(infoPtr);
ICONINFO iconInfo;
BITMAP bm;
BITMAP bm = { 0 };
UINT dtStyle = BUTTON_BStoDT( style, ex_style );
RECT r = *rc;
INT n;
/* Calculate label rectangle according to label type */
switch (style & (BS_ICON|BS_BITMAP))
/* FIXME: Doesn't support showing both image and text yet */
if (infoPtr->u.image)
{
case BS_TEXT:
{
HFONT hFont, hPrevFont = 0;
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);
}
if (!(text = get_button_text( infoPtr ))) goto empty_rect;
if (!text[0])
{
heap_free( text );
goto empty_rect;
}
if ((hFont = infoPtr->font)) hPrevFont = SelectObject( hdc, hFont );
DrawTextW(hdc, text, -1, &r, dtStyle | DT_CALCRECT);
if (hPrevFont) SelectObject( hdc, hPrevFont );
heap_free( text );
break;
}
case BS_ICON:
if (!GetIconInfo(infoPtr->u.icon, &iconInfo))
goto empty_rect;
GetObjectW (iconInfo.hbmColor, sizeof(BITMAP), &bm);
r.right = r.left + bm.bmWidth;
r.bottom = r.top + bm.bmHeight;
DeleteObject(iconInfo.hbmColor);
DeleteObject(iconInfo.hbmMask);
break;
case BS_BITMAP:
if (!GetObjectW( infoPtr->u.bitmap, sizeof(BITMAP), &bm))
goto empty_rect;
r.right = r.left + bm.bmWidth;
r.bottom = r.top + bm.bmHeight;
break;
default:
empty_rect:
rc->right = r.left;
rc->bottom = r.top;
return (UINT)-1;
r.right = r.left + bm.bmWidth;
r.bottom = r.top + bm.bmHeight;
}
else if (text && text[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;
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).
@ -934,28 +913,30 @@ static void BUTTON_DrawLabel(const BUTTON_INFO *infoPtr, HDC hdc, UINT dtFlags,
flags |= DSS_MONO;
}
switch (style & (BS_ICON|BS_BITMAP))
/* FIXME: Support drawing label with both image and text */
if (infoPtr->u.image != 0)
{
case BS_TEXT:
/* DST_COMPLEX -- is 0 */
lpOutputProc = BUTTON_DrawTextCallback;
if (!(text = get_button_text( infoPtr ))) return;
lp = (LPARAM)text;
wp = dtFlags;
break;
case BS_ICON:
flags |= DST_ICON;
lp = (LPARAM)infoPtr->u.icon;
break;
case BS_BITMAP:
flags |= DST_BITMAP;
lp = (LPARAM)infoPtr->u.bitmap;
break;
default:
return;
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;
}
DrawStateW(hdc, hbr, lpOutputProc, lp, wp, rc->left, rc->top,

View File

@ -962,6 +962,239 @@ static void test_note(void)
}
}
static void test_bm_get_set_image(void)
{
HWND hwnd;
HDC hdc;
HBITMAP hbmp1x1;
HBITMAP hbmp2x2;
HBITMAP hmask2x2;
ICONINFO icon_info2x2;
HICON hicon2x2;
HBITMAP hbmp;
HICON hicon;
ICONINFO icon_info;
BITMAP bm;
static const DWORD default_style = BS_PUSHBUTTON | WS_TABSTOP | WS_POPUP | WS_VISIBLE;
hdc = GetDC(0);
hbmp1x1 = CreateCompatibleBitmap(hdc, 1, 1);
hbmp2x2 = CreateCompatibleBitmap(hdc, 2, 2);
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(hbmp1x1, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
bm.bmWidth, bm.bmHeight);
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(hbmp2x2, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
bm.bmWidth, bm.bmHeight);
hmask2x2 = CreateCompatibleBitmap(hdc, 2, 2);
ZeroMemory(&icon_info2x2, sizeof(icon_info2x2));
icon_info2x2.fIcon = TRUE;
icon_info2x2.hbmMask = hmask2x2;
icon_info2x2.hbmColor = hbmp2x2;
hicon2x2 = CreateIconIndirect(&icon_info2x2);
ok(hicon2x2 !=NULL, "Expect CreateIconIndirect() success\n");
ZeroMemory(&icon_info, sizeof(icon_info));
ok(GetIconInfo(hicon2x2, &icon_info), "Expect GetIconInfo() success\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
bm.bmWidth, bm.bmHeight);
DeleteObject(icon_info.hbmColor);
DeleteObject(icon_info.hbmMask);
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
0, 0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
/* Get image when image is not set */
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
ok(hbmp == 0, "Expect hbmp == 0\n");
/* Set image */
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1x1);
ok(hbmp == 0, "Expect hbmp == 0\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
ok(hbmp != 0, "Expect hbmp != 0\n");
/* Set null resets image */
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, 0);
ok(hbmp != 0, "Expect hbmp != 0\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
ok(hbmp == 0, "Expect hbmp == 0\n");
DestroyWindow(hwnd);
/* Set bitmap with BS_BITMAP */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
0, 0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1x1);
ok(hbmp == 0, "Expect hbmp == 0\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
ok(hbmp != 0, "Expect hbmp != 0\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
bm.bmWidth, bm.bmHeight);
DestroyWindow(hwnd);
/* Set bitmap without BS_BITMAP */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style, 0, 0, 100, 100, 0, 0, 0, 0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1x1);
ok(hbmp == 0, "Expect hbmp == 0\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
if (hbmp == 0)
{
/* on xp or 2003*/
win_skip("Show both image and text is not supported. Skip following tests.\n");
DestroyWindow(hwnd);
goto done;
}
ok(hbmp != 0, "Expect hbmp != 0\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
bm.bmWidth, bm.bmHeight);
DestroyWindow(hwnd);
/* Set icon with BS_ICON */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
ok(hicon == 0, "Expect hicon == 0\n");
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
ok(hicon != 0, "Expect hicon != 0\n");
ZeroMemory(&icon_info, sizeof(icon_info));
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
bm.bmWidth, bm.bmHeight);
DeleteObject(icon_info.hbmColor);
DeleteObject(icon_info.hbmMask);
DestroyWindow(hwnd);
/* Set icon without BS_ICON */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style, 0, 0, 100, 100, 0, 0, 0, 0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
ok(hicon == 0, "Expect hicon == 0\n");
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
ok(hicon != 0, "Expect hicon != 0\n");
ZeroMemory(&icon_info, sizeof(icon_info));
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
bm.bmWidth, bm.bmHeight);
DeleteObject(icon_info.hbmColor);
DeleteObject(icon_info.hbmMask);
DestroyWindow(hwnd);
/* Set icon with BS_BITMAP */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
0, 0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
ok(hicon == 0, "Expect hicon == 0\n");
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
ok(hicon != 0, "Expect hicon != 0\n");
ZeroMemory(&icon_info, sizeof(icon_info));
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
bm.bmWidth, bm.bmHeight);
DeleteObject(icon_info.hbmColor);
DeleteObject(icon_info.hbmMask);
DestroyWindow(hwnd);
/* Set bitmap with BS_ICON */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1x1);
ok(hbmp == 0, "Expect hbmp == 0\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
ok(hbmp != 0, "Expect hbmp != 0\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
bm.bmWidth, bm.bmHeight);
DestroyWindow(hwnd);
/* Set bitmap with BS_BITMAP and IMAGE_ICON*/
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
0, 0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hbmp1x1);
ok(hbmp == 0, "Expect hbmp == 0\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
ok(hbmp != 0, "Expect hbmp != 0\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
bm.bmWidth, bm.bmHeight);
DestroyWindow(hwnd);
/* Set icon with BS_ICON and IMAGE_BITMAP */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hicon2x2);
ok(hicon == 0, "Expect hicon == 0\n");
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
ok(hicon != 0, "Expect hicon != 0\n");
ZeroMemory(&icon_info, sizeof(icon_info));
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(icon_info.hbmColor, sizeof(BITMAP), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
bm.bmWidth, bm.bmHeight);
DeleteObject(icon_info.hbmColor);
DeleteObject(icon_info.hbmMask);
DestroyWindow(hwnd);
/* Set bitmap with BS_ICON and IMAGE_ICON */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0, 0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hbmp1x1);
ok(hbmp == 0, "Expect hbmp == 0\n");
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
ok(hbmp != 0, "Expect hbmp != 0\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
bm.bmWidth, bm.bmHeight);
DestroyWindow(hwnd);
/* Set icon with BS_BITMAP and IMAGE_BITMAP */
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0, 0, 0);
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hicon2x2);
ok(hicon == 0, "Expect hicon == 0\n");
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
ok(hicon != 0, "Expect hicon != 0\n");
ZeroMemory(&icon_info, sizeof(icon_info));
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
ZeroMemory(&bm, sizeof(bm));
ok(GetObjectW(icon_info.hbmColor, sizeof(BITMAP), &bm), "Expect GetObjectW() success\n");
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
bm.bmWidth, bm.bmHeight);
DeleteObject(icon_info.hbmColor);
DeleteObject(icon_info.hbmMask);
DestroyWindow(hwnd);
done:
DestroyIcon(hicon2x2);
DeleteObject(hmask2x2);
DeleteObject(hbmp2x2);
DeleteObject(hbmp1x1);
ReleaseDC(0, hdc);
}
static void register_parent_class(void)
{
WNDCLASSA cls;
@ -1054,6 +1287,7 @@ START_TEST(button)
test_button_messages();
test_note();
test_button_data();
test_bm_get_set_image();
unload_v6_module(ctx_cookie, hCtx);
}