[1/2] gdiplus: added GdipCreateBitmapFromHICON

Nikolay Sivov bunglehead at gmail.com
Sat Dec 6 16:22:53 CST 2008


Changelog:
    - added GdipCreateBitmapFromHICON

>From bb36470429d754f9cc6cbaf754c4f4c04e741c7b Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Sun, 7 Dec 2008 01:09:15 +0300
Subject:  added GdipCreateBitmapFromHICON

---
 dlls/gdiplus/Makefile.in   |    2 +-
 dlls/gdiplus/gdiplus.spec  |    2 +-
 dlls/gdiplus/image.c       |   54 ++++++++++++++++++++++++++++++++++++++++++
 dlls/gdiplus/tests/image.c |   56 ++++++++++++++++++++++++++++++++++++++++++++
 include/gdiplusflat.h      |    1 +
 include/shellapi.h         |    1 +
 6 files changed, 114 insertions(+), 2 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 b3d2103..70e4dc7 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 0c61056..bdd28fc 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -18,16 +18,21 @@
 
 #include <stdarg.h>
 
+#define NONAMELESSUNION
+
 #include "windef.h"
 #include "winbase.h"
 #include "winuser.h"
 #include "wingdi.h"
 
 #define COBJMACROS
+
 #include "objbase.h"
 #include "olectl.h"
 #include "ole2.h"
 
+#include "shellapi.h"
+
 #include "initguid.h"
 #include "gdiplus.h"
 #include "gdiplus_private.h"
@@ -409,6 +414,55 @@ GpStatus WINGDIPAPI GdipConvertToEmfPlus(const GpGraphics* ref,
     return NotImplemented;
 }
 
+GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
+{
+    HICON icon_copy;
+    PICTDESC desc;
+    ICONINFO iinfo;
+
+    TRACE("%p %p\n", hicon, bitmap);
+
+    if(!bitmap)
+        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;
+    }
+
+    /* FIXME: set format value properly */
+    GetIconInfo(icon_copy, &iinfo);
+    if(iinfo.hbmColor)
+        (*bitmap)->format = PixelFormatGDI;
+    else
+        (*bitmap)->format = PixelFormat1bppIndexed;
+
+    DeleteObject(iinfo.hbmColor);
+    DeleteObject(iinfo.hbmMask);
+
+    (*bitmap)->image.type  = ImageTypeBitmap;
+    (*bitmap)->image.flags = ImageFlagsNone;
+    (*bitmap)->width  = ipicture_pixel_width((*bitmap)->image.picture);
+    (*bitmap)->height = ipicture_pixel_height((*bitmap)->image.picture);
+
+    return Ok;
+}
+
 /* FIXME: this should create a bitmap in the given size with the attributes
  * (resolution etc.) of the graphics object */
 GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT width, INT height,
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 6000dde..cc8f01b 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -530,6 +530,61 @@ 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;
+    HDC hdc;
+    UINT display_bpp;
+    ICONINFO info;
+    HICON hIcon;
+    GpStatus stat;
+    GpBitmap *bitmap;
+    UINT dim;
+    ImageType type;
+
+    /* NULL */
+    stat = GdipCreateBitmapFromHICON(NULL, NULL);
+    expect(InvalidParameter, stat);
+    stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
+    expect(InvalidParameter, stat);
+
+    hdc = GetDC(0);
+    display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
+
+    hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
+    ok(hbmMask != 0, "CreateBitmap failed\n");
+    hbmColor = CreateBitmap(16, 16, 1, display_bpp, 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");
+
+    stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
+    expect(Ok, stat);
+    /* 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);
+    GdipDisposeImage((GpImage*)bitmap);
+
+    DestroyIcon(hIcon);
+    DeleteObject(hbmMask);
+    DeleteObject(hbmColor);
+    ReleaseDC(0, hdc);
+}
+
 START_TEST(image)
 {
     struct GdiplusStartupInput gdiplusStartupInput;
@@ -553,6 +608,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 1f93258..2eba874 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 67e8923..2aa5258 100644
--- a/include/shellapi.h
+++ b/include/shellapi.h
@@ -480,6 +480,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.4.4.4






More information about the wine-patches mailing list