gdiplus: GdipCreateBitmapFromHICON implemented (with some tests)
Nikolay Sivov
bunglehead at gmail.com
Wed Jan 28 14:58:39 CST 2009
Changelog:
- GdipCreateBitmapFromHICON implemented (with some tests)
>From 08a921cabfd812ae72e539ccab4360c5e90e742d Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Wed, 28 Jan 2009 23:33:29 +0300
Subject: GdipCreateBitmapFromHICON implemented (with some tests)
---
dlls/gdiplus/Makefile.in | 2 +-
dlls/gdiplus/gdiplus.spec | 2 +-
dlls/gdiplus/image.c | 47 +++++++++++++++++
dlls/gdiplus/tests/Makefile.in | 2 +-
dlls/gdiplus/tests/image.c | 109 ++++++++++++++++++++++++++++++++++++++++
include/gdiplusflat.h | 1 +
include/shellapi.h | 1 +
7 files changed, 161 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/Makefile.in b/dlls/gdiplus/Makefile.in
index de88d5e..338c900 100644
--- a/dlls/gdiplus/Makefile.in
+++ b/dlls/gdiplus/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = gdiplus.dll
IMPORTLIB = gdiplus
-IMPORTS = uuid shlwapi oleaut32 ole32 user32 gdi32 kernel32
+IMPORTS = uuid shlwapi oleaut32 ole32 user32 gdi32 kernel32 shell32
C_SRCS = \
brush.c \
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index 3716207..f5bb89d 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -76,7 +76,7 @@
@ stdcall GdipCreateBitmapFromGdiDib(ptr ptr ptr)
@ stdcall GdipCreateBitmapFromGraphics(long long ptr ptr)
@ stdcall GdipCreateBitmapFromHBITMAP(long long ptr)
-@ stub GdipCreateBitmapFromHICON
+@ stdcall GdipCreateBitmapFromHICON(long ptr)
@ stdcall GdipCreateBitmapFromResource(long wstr ptr)
@ stdcall GdipCreateBitmapFromScan0(long long long long ptr ptr)
@ stdcall GdipCreateBitmapFromStream(ptr ptr)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 02f8f5a..1392c3c 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -18,6 +18,8 @@
#include <stdarg.h>
+#define NONAMELESSUNION
+
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
@@ -28,6 +30,8 @@
#include "olectl.h"
#include "ole2.h"
+#include "shellapi.h"
+
#include "initguid.h"
#include "gdiplus.h"
#include "gdiplus_private.h"
@@ -429,6 +433,49 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT width, INT height,
return ret;
}
+GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
+{
+ HICON icon_copy;
+ ICONINFO iinfo;
+ PICTDESC desc;
+
+ TRACE("%p, %p\n", hicon, bitmap);
+
+ if(!bitmap || !GetIconInfo(hicon, &iinfo))
+ return InvalidParameter;
+
+ *bitmap = GdipAlloc(sizeof(GpBitmap));
+ if(!*bitmap) return OutOfMemory;
+
+ icon_copy = DuplicateIcon(NULL, hicon);
+ if(!icon_copy){
+ GdipFree(*bitmap);
+ return InvalidParameter;
+ }
+
+ desc.cbSizeofstruct = sizeof(PICTDESC);
+ desc.picType = PICTYPE_ICON;
+ desc.u.icon.hicon = icon_copy;
+
+ if(OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE,
+ (LPVOID*) &((*bitmap)->image.picture)) != S_OK){
+ DestroyIcon(icon_copy);
+ GdipFree(*bitmap);
+ return GenericError;
+ }
+
+ (*bitmap)->format = PixelFormat32bppARGB;
+ (*bitmap)->image.type = ImageTypeBitmap;
+ (*bitmap)->image.flags = ImageFlagsNone;
+ (*bitmap)->width = ipicture_pixel_width((*bitmap)->image.picture);
+ (*bitmap)->height = ipicture_pixel_height((*bitmap)->image.picture);
+
+ DeleteObject(iinfo.hbmColor);
+ DeleteObject(iinfo.hbmMask);
+
+ return Ok;
+}
+
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
PixelFormat format, BYTE* scan0, GpBitmap** bitmap)
{
diff --git a/dlls/gdiplus/tests/Makefile.in b/dlls/gdiplus/tests/Makefile.in
index 7dba3da..1f7f822 100644
--- a/dlls/gdiplus/tests/Makefile.in
+++ b/dlls/gdiplus/tests/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../../..
SRCDIR = @srcdir@
VPATH = @srcdir@
TESTDLL = gdiplus.dll
-IMPORTS = gdiplus user32 gdi32 kernel32
+IMPORTS = gdiplus user32 gdi32 kernel32 ole32
CTESTS = \
brush.c \
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 19f0500..985285b 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -18,11 +18,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <initguid.h>
+
#include "windows.h"
#include "gdiplus.h"
#include "wine/test.h"
#include <math.h>
#include "wingdi.h"
+#include "objbase.h"
#define expect(expected, got) ok(((UINT)got) == ((UINT)expected), "Expected %.8x, got %.8x\n", (UINT)expected, (UINT)got)
@@ -530,6 +533,111 @@ static void test_testcontrol(void)
ok(param != 0, "Build number expected, got %u\n", param);
}
+static void test_fromhicon(void)
+{
+ static const BYTE bmp_bits[1024];
+ HBITMAP hbmMask, hbmColor;
+ ICONINFO info;
+ HICON hIcon;
+ GpStatus stat;
+ GpBitmap *bitmap = NULL;
+ UINT dim;
+ ImageType type;
+ PixelFormat format;
+ GUID raw;
+ WCHAR bufferW[39];
+ char buffer[39];
+ char buffer2[39];
+
+ /* NULL */
+ stat = GdipCreateBitmapFromHICON(NULL, NULL);
+ expect(InvalidParameter, stat);
+ stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
+ expect(InvalidParameter, stat);
+
+ /* color icon 1 bit */
+ hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
+ ok(hbmMask != 0, "CreateBitmap failed\n");
+ hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
+ ok(hbmColor != 0, "CreateBitmap failed\n");
+ info.fIcon = TRUE;
+ info.xHotspot = 8;
+ info.yHotspot = 8;
+ info.hbmMask = hbmMask;
+ info.hbmColor = hbmColor;
+ hIcon = CreateIconIndirect(&info);
+ ok(hIcon != 0, "CreateIconIndirect failed\n");
+ DeleteObject(hbmMask);
+ DeleteObject(hbmColor);
+
+ stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
+ expect(Ok, stat);
+ if(stat == Ok){
+ /* check attributes */
+ stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
+ expect(Ok, stat);
+ expect(16, dim);
+ stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
+ expect(Ok, stat);
+ expect(16, dim);
+ stat = GdipGetImageType((GpImage*)bitmap, &type);
+ expect(Ok, stat);
+ expect(ImageTypeBitmap, type);
+ stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
+ expect(PixelFormat32bppARGB, format);
+ /* raw format */
+ stat = GdipGetImageRawFormat((GpImage*)bitmap, &raw);
+ StringFromGUID2(&raw, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
+ WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
+ StringFromGUID2(&ImageFormatMemoryBMP, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
+ WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer2, sizeof(buffer2), NULL, NULL);
+ todo_wine ok(IsEqualGUID(&raw, &ImageFormatMemoryBMP), "Expected format %s, got %s\n", buffer2, buffer);
+ GdipDisposeImage((GpImage*)bitmap);
+ }
+ DestroyIcon(hIcon);
+
+ /* color icon 8 bpp */
+ hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
+ ok(hbmMask != 0, "CreateBitmap failed\n");
+ hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
+ ok(hbmColor != 0, "CreateBitmap failed\n");
+ info.fIcon = TRUE;
+ info.xHotspot = 8;
+ info.yHotspot = 8;
+ info.hbmMask = hbmMask;
+ info.hbmColor = hbmColor;
+ hIcon = CreateIconIndirect(&info);
+ ok(hIcon != 0, "CreateIconIndirect failed\n");
+ DeleteObject(hbmMask);
+ DeleteObject(hbmColor);
+
+ stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
+ expect(Ok, stat);
+ if(stat == Ok){
+ /* check attributes */
+ stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
+ expect(Ok, stat);
+ expect(16, dim);
+ stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
+ expect(Ok, stat);
+ expect(16, dim);
+ stat = GdipGetImageType((GpImage*)bitmap, &type);
+ expect(Ok, stat);
+ expect(ImageTypeBitmap, type);
+ stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
+ expect(PixelFormat32bppARGB, format);
+ /* raw format */
+ stat = GdipGetImageRawFormat((GpImage*)bitmap, &raw);
+ StringFromGUID2(&raw, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
+ WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
+ StringFromGUID2(&ImageFormatMemoryBMP, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
+ WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer2, sizeof(buffer2), NULL, NULL);
+ todo_wine ok(IsEqualGUID(&raw, &ImageFormatMemoryBMP), "Expected format %s, got %s\n", buffer2, buffer);
+ GdipDisposeImage((GpImage*)bitmap);
+ }
+ DestroyIcon(hIcon);
+}
+
START_TEST(image)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -553,6 +661,7 @@ START_TEST(image)
test_GdipGetImageFlags();
test_GdipCloneImage();
test_testcontrol();
+ test_fromhicon();
GdiplusShutdown(gdiplusToken);
}
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index 1a39dee..7553c5d 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -49,6 +49,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromFileICM(GDIPCONST WCHAR*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromGdiDib(GDIPCONST BITMAPINFO*,VOID*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT,INT,GpGraphics*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP, HPALETTE, GpBitmap**);
+GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON, GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromResource(HINSTANCE,GDIPCONST WCHAR*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT,INT,INT,PixelFormat,BYTE*,
GpBitmap**);
diff --git a/include/shellapi.h b/include/shellapi.h
index 930f261..baad908 100644
--- a/include/shellapi.h
+++ b/include/shellapi.h
@@ -482,6 +482,7 @@ HRESULT WINAPI SHQueryRecycleBinW(LPCWSTR,LPSHQUERYRBINFO);
*/
LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR,int*);
+HICON WINAPI DuplicateIcon(HINSTANCE,HICON);
HICON WINAPI ExtractIconA(HINSTANCE,LPCSTR,UINT);
HICON WINAPI ExtractIconW(HINSTANCE,LPCWSTR,UINT);
#define ExtractIcon WINELIB_NAME_AW(ExtractIcon)
--
1.5.6.5
More information about the wine-patches
mailing list