user32: Copy icon bits by hand in CreateIconIndirect if the bitmaps can't be selected into a DC.
This commit is contained in:
parent
f90b6d5af6
commit
e2cb88ec2d
|
@ -1830,6 +1830,43 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* copy an icon bitmap, even when it can't be selected into a DC */
|
||||||
|
/* helper for CreateIconIndirect */
|
||||||
|
static void stretch_blt_icon( HDC hdc_dst, int dst_x, int dst_y, int dst_width, int dst_height,
|
||||||
|
HBITMAP src, int width, int height )
|
||||||
|
{
|
||||||
|
HDC hdc = CreateCompatibleDC( 0 );
|
||||||
|
|
||||||
|
if (!SelectObject( hdc, src ) || 1) /* do it the hard way */
|
||||||
|
{
|
||||||
|
BITMAPINFO *info;
|
||||||
|
void *bits;
|
||||||
|
|
||||||
|
if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) return;
|
||||||
|
info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
info->bmiHeader.biWidth = width;
|
||||||
|
info->bmiHeader.biHeight = height;
|
||||||
|
info->bmiHeader.biPlanes = GetDeviceCaps( hdc_dst, PLANES );
|
||||||
|
info->bmiHeader.biBitCount = GetDeviceCaps( hdc_dst, BITSPIXEL );
|
||||||
|
info->bmiHeader.biCompression = BI_RGB;
|
||||||
|
info->bmiHeader.biSizeImage = height * get_dib_width_bytes( width, info->bmiHeader.biBitCount );
|
||||||
|
info->bmiHeader.biXPelsPerMeter = 0;
|
||||||
|
info->bmiHeader.biYPelsPerMeter = 0;
|
||||||
|
info->bmiHeader.biClrUsed = 0;
|
||||||
|
info->bmiHeader.biClrImportant = 0;
|
||||||
|
bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
|
||||||
|
if (bits && GetDIBits( hdc, src, 0, height, bits, info, DIB_RGB_COLORS ))
|
||||||
|
StretchDIBits( hdc_dst, dst_x, dst_y, dst_width, dst_height,
|
||||||
|
0, 0, width, height, bits, info, DIB_RGB_COLORS, SRCCOPY );
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, bits );
|
||||||
|
HeapFree( GetProcessHeap(), 0, info );
|
||||||
|
}
|
||||||
|
else StretchBlt( hdc_dst, dst_x, dst_y, dst_width, dst_height, hdc, 0, 0, width, height, SRCCOPY );
|
||||||
|
|
||||||
|
DeleteDC( hdc );
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* CreateIconIndirect (USER32.@)
|
* CreateIconIndirect (USER32.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1839,7 +1876,7 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
|
||||||
HICON hObj;
|
HICON hObj;
|
||||||
HBITMAP color = 0, mask;
|
HBITMAP color = 0, mask;
|
||||||
int width, height;
|
int width, height;
|
||||||
HDC src, dst;
|
HDC hdc;
|
||||||
|
|
||||||
TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n",
|
TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n",
|
||||||
iconinfo->hbmColor, iconinfo->hbmMask,
|
iconinfo->hbmColor, iconinfo->hbmMask,
|
||||||
|
@ -1875,28 +1912,22 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
|
||||||
mask = CreateBitmap( width, height, 1, 1, NULL );
|
mask = CreateBitmap( width, height, 1, 1, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
src = CreateCompatibleDC( 0 );
|
hdc = CreateCompatibleDC( 0 );
|
||||||
dst = CreateCompatibleDC( 0 );
|
SelectObject( hdc, mask );
|
||||||
|
stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmMask, bmpAnd.bmWidth, bmpAnd.bmHeight );
|
||||||
SelectObject( src, iconinfo->hbmMask );
|
|
||||||
SelectObject( dst, mask );
|
|
||||||
StretchBlt( dst, 0, 0, width, height, src, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, SRCCOPY );
|
|
||||||
|
|
||||||
if (color)
|
if (color)
|
||||||
{
|
{
|
||||||
SelectObject( src, iconinfo->hbmColor );
|
SelectObject( hdc, color );
|
||||||
SelectObject( dst, color );
|
stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmColor, width, height );
|
||||||
BitBlt( dst, 0, 0, width, height, src, 0, 0, SRCCOPY );
|
|
||||||
}
|
}
|
||||||
else if (iconinfo->hbmColor)
|
else if (iconinfo->hbmColor)
|
||||||
{
|
{
|
||||||
SelectObject( src, iconinfo->hbmColor );
|
stretch_blt_icon( hdc, 0, height, width, height, iconinfo->hbmColor, width, height );
|
||||||
BitBlt( dst, 0, height, width, height, src, 0, 0, SRCCOPY );
|
|
||||||
}
|
}
|
||||||
else height /= 2;
|
else height /= 2;
|
||||||
|
|
||||||
DeleteDC( src );
|
DeleteDC( hdc );
|
||||||
DeleteDC( dst );
|
|
||||||
|
|
||||||
hObj = alloc_icon_handle();
|
hObj = alloc_icon_handle();
|
||||||
if (hObj)
|
if (hObj)
|
||||||
|
|
Loading…
Reference in New Issue