Nikolay Sivov : gdiplus: Implemented GdipCreateBitmapFromHICON (with tests) .

Alexandre Julliard julliard at winehq.org
Tue Feb 3 09:13:14 CST 2009


Module: wine
Branch: master
Commit: 5bc54ed97ecd281a2ef4d07473d72f1e50cd9ad5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5bc54ed97ecd281a2ef4d07473d72f1e50cd9ad5

Author: Nikolay Sivov <bunglehead at gmail.com>
Date:   Mon Feb  2 19:15:53 2009 +0300

gdiplus: Implemented GdipCreateBitmapFromHICON (with tests).

---

 dlls/gdiplus/gdiplus.spec      |    2 +-
 dlls/gdiplus/image.c           |   46 ++++++++++++++++
 dlls/gdiplus/tests/Makefile.in |    2 +-
 dlls/gdiplus/tests/image.c     |  111 +++++++++++++++++++++++++++++++++++++++-
 include/gdiplusflat.h          |    1 +
 5 files changed, 158 insertions(+), 4 deletions(-)

diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index 7e7bfbf..f9d47d9 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..9944322 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"
@@ -429,6 +431,50 @@ 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 = CreateIconIndirect(&iinfo);
+
+    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..ac5589d 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 ole32 user32 gdi32 kernel32
 
 CTESTS = \
 	brush.c \
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 19f0500..6619759 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -18,11 +18,12 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <math.h>
+
+#include "initguid.h"
 #include "windows.h"
 #include "gdiplus.h"
 #include "wine/test.h"
-#include <math.h>
-#include "wingdi.h"
 
 #define expect(expected, got) ok(((UINT)got) == ((UINT)expected), "Expected %.8x, got %.8x\n", (UINT)expected, (UINT)got)
 
@@ -530,6 +531,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 +659,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 cb53ea4..dd01d1b 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**);




More information about the wine-cvs mailing list