Alexandre Julliard : user32: Copy icon bits by hand in CreateIconIndirect if the bitmaps can' t be selected into a DC.
Alexandre Julliard
julliard at winehq.org
Wed May 26 11:49:07 CDT 2010
Module: wine
Branch: master
Commit: e2cb88ec2de717b844c2564e4b0ddc6f09e4e76e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e2cb88ec2de717b844c2564e4b0ddc6f09e4e76e
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed May 26 15:57:41 2010 +0200
user32: Copy icon bits by hand in CreateIconIndirect if the bitmaps can't be selected into a DC.
---
dlls/user32/cursoricon.c | 59 +++++++++++++++++++++++++++++++++++-----------
1 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 1217440..8910985 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -1830,6 +1830,43 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
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.@)
*/
@@ -1839,7 +1876,7 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
HICON hObj;
HBITMAP color = 0, mask;
int width, height;
- HDC src, dst;
+ HDC hdc;
TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n",
iconinfo->hbmColor, iconinfo->hbmMask,
@@ -1875,28 +1912,22 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
mask = CreateBitmap( width, height, 1, 1, NULL );
}
- src = CreateCompatibleDC( 0 );
- dst = CreateCompatibleDC( 0 );
-
- SelectObject( src, iconinfo->hbmMask );
- SelectObject( dst, mask );
- StretchBlt( dst, 0, 0, width, height, src, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, SRCCOPY );
+ hdc = CreateCompatibleDC( 0 );
+ SelectObject( hdc, mask );
+ stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmMask, bmpAnd.bmWidth, bmpAnd.bmHeight );
if (color)
{
- SelectObject( src, iconinfo->hbmColor );
- SelectObject( dst, color );
- BitBlt( dst, 0, 0, width, height, src, 0, 0, SRCCOPY );
+ SelectObject( hdc, color );
+ stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmColor, width, height );
}
else if (iconinfo->hbmColor)
{
- SelectObject( src, iconinfo->hbmColor );
- BitBlt( dst, 0, height, width, height, src, 0, 0, SRCCOPY );
+ stretch_blt_icon( hdc, 0, height, width, height, iconinfo->hbmColor, width, height );
}
else height /= 2;
- DeleteDC( src );
- DeleteDC( dst );
+ DeleteDC( hdc );
hObj = alloc_icon_handle();
if (hObj)
More information about the wine-cvs
mailing list