user32: Handle monochrome icons in CreateIcon() and CreateCursor() instead of CreateIconIndirect().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1bfa845a67
commit
db2b266c57
|
@ -1570,29 +1570,47 @@ static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static HBITMAP create_masked_bitmap( int width, int height, const void *and, const void *xor )
|
||||||
|
{
|
||||||
|
HDC dc = CreateCompatibleDC( 0 );
|
||||||
|
HBITMAP bitmap;
|
||||||
|
|
||||||
|
const BITMAPINFO bitmap_info =
|
||||||
|
{
|
||||||
|
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
|
||||||
|
.bmiHeader.biWidth = width,
|
||||||
|
.bmiHeader.biHeight = height * 2,
|
||||||
|
.bmiHeader.biPlanes = 1,
|
||||||
|
.bmiHeader.biBitCount = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
bitmap = CreateBitmap( width, height * 2, 1, 1, NULL );
|
||||||
|
SetDIBits( dc, bitmap, 0, height, and, &bitmap_info, FALSE );
|
||||||
|
SetDIBits( dc, bitmap, height, height, xor, &bitmap_info, FALSE );
|
||||||
|
DeleteDC( dc );
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CreateCursor (USER32.@)
|
* CreateCursor (USER32.@)
|
||||||
*/
|
*/
|
||||||
HCURSOR WINAPI CreateCursor( HINSTANCE hInstance,
|
HCURSOR WINAPI CreateCursor( HINSTANCE instance, int hotspot_x, int hotspot_y,
|
||||||
INT xHotSpot, INT yHotSpot,
|
int width, int height, const void *and, const void *xor )
|
||||||
INT nWidth, INT nHeight,
|
|
||||||
LPCVOID lpANDbits, LPCVOID lpXORbits )
|
|
||||||
{
|
{
|
||||||
ICONINFO info;
|
ICONINFO info;
|
||||||
HCURSOR hCursor;
|
HCURSOR cursor;
|
||||||
|
|
||||||
TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
|
TRACE( "hotspot (%d,%d), size %dx%d\n", hotspot_x, hotspot_y, width, height );
|
||||||
nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits);
|
|
||||||
|
|
||||||
info.fIcon = FALSE;
|
info.fIcon = FALSE;
|
||||||
info.xHotspot = xHotSpot;
|
info.xHotspot = hotspot_x;
|
||||||
info.yHotspot = yHotSpot;
|
info.yHotspot = hotspot_y;
|
||||||
info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpANDbits );
|
info.hbmColor = NULL;
|
||||||
info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, lpXORbits );
|
info.hbmMask = create_masked_bitmap( width, height, and, xor );
|
||||||
hCursor = CreateIconIndirect( &info );
|
cursor = CreateIconIndirect( &info );
|
||||||
DeleteObject( info.hbmMask );
|
DeleteObject( info.hbmMask );
|
||||||
DeleteObject( info.hbmColor );
|
return cursor;
|
||||||
return hCursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1615,33 +1633,34 @@ HCURSOR WINAPI CreateCursor( HINSTANCE hInstance,
|
||||||
*
|
*
|
||||||
* FIXME: Do we need to resize the bitmaps?
|
* FIXME: Do we need to resize the bitmaps?
|
||||||
*/
|
*/
|
||||||
HICON WINAPI CreateIcon(
|
HICON WINAPI CreateIcon( HINSTANCE instance, int width, int height, BYTE planes,
|
||||||
HINSTANCE hInstance, /* [in] the application's hInstance */
|
BYTE depth, const void *and, const void *xor )
|
||||||
INT nWidth, /* [in] the width of the provided bitmaps */
|
|
||||||
INT nHeight, /* [in] the height of the provided bitmaps */
|
|
||||||
BYTE bPlanes, /* [in] the number of planes in the provided bitmaps */
|
|
||||||
BYTE bBitsPixel, /* [in] the number of bits per pixel of the lpXORbits bitmap */
|
|
||||||
LPCVOID lpANDbits, /* [in] a monochrome bitmap representing the icon's mask */
|
|
||||||
LPCVOID lpXORbits) /* [in] the icon's 'color' bitmap */
|
|
||||||
{
|
{
|
||||||
ICONINFO iinfo;
|
ICONINFO info;
|
||||||
HICON hIcon;
|
HICON icon;
|
||||||
|
|
||||||
TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
|
TRACE_(icon)( "%dx%d, planes %d, depth %d\n", width, height, planes, depth );
|
||||||
nWidth, nHeight, bPlanes, bBitsPixel, lpXORbits, lpANDbits);
|
|
||||||
|
|
||||||
iinfo.fIcon = TRUE;
|
info.fIcon = TRUE;
|
||||||
iinfo.xHotspot = nWidth / 2;
|
info.xHotspot = width / 2;
|
||||||
iinfo.yHotspot = nHeight / 2;
|
info.yHotspot = height / 2;
|
||||||
iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpANDbits );
|
if (depth == 1)
|
||||||
iinfo.hbmColor = CreateBitmap( nWidth, nHeight, bPlanes, bBitsPixel, lpXORbits );
|
{
|
||||||
|
info.hbmColor = NULL;
|
||||||
|
info.hbmMask = create_masked_bitmap( width, height, and, xor );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.hbmColor = CreateBitmap( width, height, planes, depth, xor );
|
||||||
|
info.hbmMask = CreateBitmap( width, height, 1, 1, and );
|
||||||
|
}
|
||||||
|
|
||||||
hIcon = CreateIconIndirect( &iinfo );
|
icon = CreateIconIndirect( &info );
|
||||||
|
|
||||||
DeleteObject( iinfo.hbmMask );
|
DeleteObject( info.hbmMask );
|
||||||
DeleteObject( iinfo.hbmColor );
|
DeleteObject( info.hbmColor );
|
||||||
|
|
||||||
return hIcon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2248,19 +2267,14 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
|
||||||
|
|
||||||
width = bmpXor.bmWidth;
|
width = bmpXor.bmWidth;
|
||||||
height = bmpXor.bmHeight;
|
height = bmpXor.bmHeight;
|
||||||
if (bmpXor.bmPlanes * bmpXor.bmBitsPixel != 1 || bmpAnd.bmPlanes * bmpAnd.bmBitsPixel != 1)
|
color = create_color_bitmap( width, height );
|
||||||
{
|
|
||||||
color = create_color_bitmap( width, height );
|
|
||||||
mask = CreateBitmap( width, height, 1, 1, NULL );
|
|
||||||
}
|
|
||||||
else mask = CreateBitmap( width, height * 2, 1, 1, NULL );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = bmpAnd.bmWidth;
|
width = bmpAnd.bmWidth;
|
||||||
height = bmpAnd.bmHeight;
|
height = bmpAnd.bmHeight;
|
||||||
mask = CreateBitmap( width, height, 1, 1, NULL );
|
|
||||||
}
|
}
|
||||||
|
mask = CreateBitmap( width, height, 1, 1, NULL );
|
||||||
|
|
||||||
hdc = CreateCompatibleDC( 0 );
|
hdc = CreateCompatibleDC( 0 );
|
||||||
SelectObject( hdc, mask );
|
SelectObject( hdc, mask );
|
||||||
|
@ -2271,10 +2285,6 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
|
||||||
SelectObject( hdc, color );
|
SelectObject( hdc, color );
|
||||||
stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmColor, width, height );
|
stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmColor, width, height );
|
||||||
}
|
}
|
||||||
else if (iconinfo->hbmColor)
|
|
||||||
{
|
|
||||||
stretch_blt_icon( hdc, 0, height, width, height, iconinfo->hbmColor, width, height );
|
|
||||||
}
|
|
||||||
else height /= 2;
|
else height /= 2;
|
||||||
|
|
||||||
DeleteDC( hdc );
|
DeleteDC( hdc );
|
||||||
|
|
|
@ -709,7 +709,8 @@ static void test_initial_cursor(void)
|
||||||
ok(error == 0xdeadbeef, "Last error: 0x%08x\n", error);
|
ok(error == 0xdeadbeef, "Last error: 0x%08x\n", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_icon_info_dbg(HICON hIcon, UINT exp_cx, UINT exp_cy, UINT exp_mask_cy, UINT exp_bpp, int line)
|
static void test_icon_info_(HICON hIcon, UINT exp_cx, UINT exp_cy,
|
||||||
|
UINT exp_mask_cy, UINT exp_bpp, UINT has_color, int line)
|
||||||
{
|
{
|
||||||
ICONINFO info;
|
ICONINFO info;
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
|
@ -726,8 +727,7 @@ static void test_icon_info_dbg(HICON hIcon, UINT exp_cx, UINT exp_cy, UINT exp_m
|
||||||
ret = GetObjectA(info.hbmMask, sizeof(bmMask), &bmMask);
|
ret = GetObjectA(info.hbmMask, sizeof(bmMask), &bmMask);
|
||||||
ok_(__FILE__, line)(ret == sizeof(bmMask), "GetObject(info.hbmMask) failed, ret %u\n", ret);
|
ok_(__FILE__, line)(ret == sizeof(bmMask), "GetObject(info.hbmMask) failed, ret %u\n", ret);
|
||||||
|
|
||||||
if (exp_bpp == 1)
|
ok_(__FILE__, line)(!!info.hbmColor == has_color, "got hbmColor %p\n", info.hbmColor);
|
||||||
ok_(__FILE__, line)(info.hbmColor == 0, "info.hbmColor should be NULL\n");
|
|
||||||
|
|
||||||
if (info.hbmColor)
|
if (info.hbmColor)
|
||||||
{
|
{
|
||||||
|
@ -790,7 +790,7 @@ static void test_icon_info_dbg(HICON hIcon, UINT exp_cx, UINT exp_cy, UINT exp_m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define test_icon_info(a,b,c,d,e) test_icon_info_dbg((a),(b),(c),(d),(e),__LINE__)
|
#define test_icon_info(a,b,c,d,e,f) test_icon_info_(a,b,c,d,e,f,__LINE__)
|
||||||
|
|
||||||
static void test_CreateIcon(void)
|
static void test_CreateIcon(void)
|
||||||
{
|
{
|
||||||
|
@ -814,12 +814,17 @@ static void test_CreateIcon(void)
|
||||||
|
|
||||||
hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, bmp_bits);
|
hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, bmp_bits);
|
||||||
ok(hIcon != 0, "CreateIcon failed\n");
|
ok(hIcon != 0, "CreateIcon failed\n");
|
||||||
test_icon_info(hIcon, 16, 16, 32, 1);
|
test_icon_info(hIcon, 16, 16, 32, 1, FALSE);
|
||||||
DestroyIcon(hIcon);
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
|
hIcon = CreateCursor(0, 8, 8, 16, 16, bmp_bits, bmp_bits);
|
||||||
|
ok(hIcon != 0, "CreateCursor failed\n");
|
||||||
|
test_icon_info(hIcon, 16, 16, 32, 1, FALSE);
|
||||||
|
DestroyCursor(hIcon);
|
||||||
|
|
||||||
hIcon = CreateIcon(0, 16, 16, 1, display_bpp, bmp_bits, bmp_bits);
|
hIcon = CreateIcon(0, 16, 16, 1, display_bpp, bmp_bits, bmp_bits);
|
||||||
ok(hIcon != 0, "CreateIcon failed\n");
|
ok(hIcon != 0, "CreateIcon failed\n");
|
||||||
test_icon_info(hIcon, 16, 16, 16, display_bpp);
|
test_icon_info(hIcon, 16, 16, 16, display_bpp, TRUE);
|
||||||
DestroyIcon(hIcon);
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
|
hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
|
||||||
|
@ -854,7 +859,7 @@ static void test_CreateIcon(void)
|
||||||
info.hbmColor = hbmColor;
|
info.hbmColor = hbmColor;
|
||||||
hIcon = CreateIconIndirect(&info);
|
hIcon = CreateIconIndirect(&info);
|
||||||
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
||||||
test_icon_info(hIcon, 16, 16, 16, display_bpp);
|
test_icon_info(hIcon, 16, 16, 16, display_bpp, TRUE);
|
||||||
DestroyIcon(hIcon);
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
DeleteObject(hbmMask);
|
DeleteObject(hbmMask);
|
||||||
|
@ -871,8 +876,17 @@ static void test_CreateIcon(void)
|
||||||
SetLastError(0xdeadbeaf);
|
SetLastError(0xdeadbeaf);
|
||||||
hIcon = CreateIconIndirect(&info);
|
hIcon = CreateIconIndirect(&info);
|
||||||
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
||||||
test_icon_info(hIcon, 16, 16, 32, 1);
|
test_icon_info(hIcon, 16, 16, 32, 1, FALSE);
|
||||||
DestroyIcon(hIcon);
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
|
info.hbmMask = hbmMask;
|
||||||
|
info.hbmColor = hbmMask;
|
||||||
|
SetLastError(0xdeadbeaf);
|
||||||
|
hIcon = CreateIconIndirect(&info);
|
||||||
|
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
||||||
|
test_icon_info(hIcon, 16, 32, 32, 1, TRUE);
|
||||||
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
DeleteObject(hbmMask);
|
DeleteObject(hbmMask);
|
||||||
|
|
||||||
for (i = 0; i <= 4; i++)
|
for (i = 0; i <= 4; i++)
|
||||||
|
@ -888,11 +902,24 @@ static void test_CreateIcon(void)
|
||||||
SetLastError(0xdeadbeaf);
|
SetLastError(0xdeadbeaf);
|
||||||
hIcon = CreateIconIndirect(&info);
|
hIcon = CreateIconIndirect(&info);
|
||||||
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
||||||
test_icon_info(hIcon, 1, i / 2, max(i,1), 1);
|
test_icon_info(hIcon, 1, i / 2, max(i,1), 1, FALSE);
|
||||||
DestroyIcon(hIcon);
|
DestroyIcon(hIcon);
|
||||||
DeleteObject(hbmMask);
|
DeleteObject(hbmMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hbmMask = CreateBitmap(16, 32, 1, 16, bmp_bits);
|
||||||
|
ok(hbmMask != 0, "CreateBitmap failed\n");
|
||||||
|
|
||||||
|
info.hbmMask = hbmMask;
|
||||||
|
info.hbmColor = 0;
|
||||||
|
SetLastError(0xdeadbeaf);
|
||||||
|
hIcon = CreateIconIndirect(&info);
|
||||||
|
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
||||||
|
test_icon_info(hIcon, 16, 16, 32, 1, FALSE);
|
||||||
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
|
DeleteObject(hbmMask);
|
||||||
|
|
||||||
/* test creating an icon from a DIB section */
|
/* test creating an icon from a DIB section */
|
||||||
|
|
||||||
bmpinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(BITMAPINFO,bmiColors[256]));
|
bmpinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(BITMAPINFO,bmiColors[256]));
|
||||||
|
@ -920,7 +947,7 @@ static void test_CreateIcon(void)
|
||||||
SetLastError(0xdeadbeaf);
|
SetLastError(0xdeadbeaf);
|
||||||
hIcon = CreateIconIndirect(&info);
|
hIcon = CreateIconIndirect(&info);
|
||||||
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
||||||
test_icon_info(hIcon, 32, 32, 32, 8);
|
test_icon_info(hIcon, 32, 32, 32, 8, TRUE);
|
||||||
DestroyIcon(hIcon);
|
DestroyIcon(hIcon);
|
||||||
DeleteObject(hbmColor);
|
DeleteObject(hbmColor);
|
||||||
|
|
||||||
|
@ -938,7 +965,7 @@ static void test_CreateIcon(void)
|
||||||
SetLastError(0xdeadbeaf);
|
SetLastError(0xdeadbeaf);
|
||||||
hIcon = CreateIconIndirect(&info);
|
hIcon = CreateIconIndirect(&info);
|
||||||
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
||||||
test_icon_info(hIcon, 32, 32, 32, 8);
|
test_icon_info(hIcon, 32, 32, 32, 8, TRUE);
|
||||||
DestroyIcon(hIcon);
|
DestroyIcon(hIcon);
|
||||||
DeleteObject(hbmColor);
|
DeleteObject(hbmColor);
|
||||||
|
|
||||||
|
@ -956,7 +983,7 @@ static void test_CreateIcon(void)
|
||||||
SetLastError(0xdeadbeaf);
|
SetLastError(0xdeadbeaf);
|
||||||
hIcon = CreateIconIndirect(&info);
|
hIcon = CreateIconIndirect(&info);
|
||||||
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
ok(hIcon != 0, "CreateIconIndirect failed\n");
|
||||||
test_icon_info(hIcon, 32, 32, 32, 8);
|
test_icon_info(hIcon, 32, 32, 32, 8, TRUE);
|
||||||
DestroyIcon(hIcon);
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
DeleteObject(hbmMask);
|
DeleteObject(hbmMask);
|
||||||
|
@ -2662,7 +2689,7 @@ static void test_PrivateExtractIcons(void)
|
||||||
ok(ret == 1, "PrivateExtractIconsA returned %u\n", ret);
|
ok(ret == 1, "PrivateExtractIconsA returned %u\n", ret);
|
||||||
ok(icon != NULL, "icon == NULL\n");
|
ok(icon != NULL, "icon == NULL\n");
|
||||||
|
|
||||||
test_icon_info(icon, 32, 32, 32, 32);
|
test_icon_info(icon, 32, 32, 32, 32, TRUE);
|
||||||
DestroyIcon(icon);
|
DestroyIcon(icon);
|
||||||
|
|
||||||
DeleteFileA("extract.ico");
|
DeleteFileA("extract.ico");
|
||||||
|
|
Loading…
Reference in New Issue