Alexandre Julliard : shell: Explicitly convert icons to 16-bit instead of casting handles.

Alexandre Julliard julliard at winehq.org
Tue Feb 2 10:45:27 CST 2010


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Feb  1 17:03:23 2010 +0100

shell: Explicitly convert icons to 16-bit instead of casting handles.

---

 dlls/shell.dll16/Makefile.in |    2 +-
 dlls/shell.dll16/shell.c     |   67 +++++++++++++++++++++++++++++++++--------
 2 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/dlls/shell.dll16/Makefile.in b/dlls/shell.dll16/Makefile.in
index 8dff0a9..36b23fc 100644
--- a/dlls/shell.dll16/Makefile.in
+++ b/dlls/shell.dll16/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = shell.dll16
-IMPORTS   = shell32 user32 advapi32 kernel32 kernel
+IMPORTS   = shell32 user32 gdi32 advapi32 kernel32 kernel
 
 EXTRADLLFLAGS = -Wb,--subsystem,win16,--main-module,shell32.dll
 EXTRARCFLAGS  = -O res16
diff --git a/dlls/shell.dll16/shell.c b/dlls/shell.dll16/shell.c
index b8d99fd..be8ffeb 100644
--- a/dlls/shell.dll16/shell.c
+++ b/dlls/shell.dll16/shell.c
@@ -52,7 +52,6 @@ extern HINSTANCE WINAPI WOWShellExecute(HWND hWnd, LPCSTR lpOperation,LPCSTR lpF
                                         LPCSTR lpParameters,LPCSTR lpDirectory,
                                         INT iShowCmd, void *callback);
 
-#define HICON_16(h32)		(LOWORD(h32))
 #define HINSTANCE_32(h16)	((HINSTANCE)(ULONG_PTR)(h16))
 #define HINSTANCE_16(h32)	(LOWORD(h32))
 
@@ -84,6 +83,50 @@ static HICON convert_icon_to_32( HICON16 icon16 )
     return ret;
 }
 
+static HICON16 convert_icon_to_16( HINSTANCE16 inst, HICON icon )
+{
+    static HICON16 (WINAPI *pCreateIcon16)(HINSTANCE16,INT16,INT16,BYTE,BYTE,LPCVOID,LPCVOID);
+    ICONINFO info;
+    BITMAP bm;
+    UINT and_size, xor_size;
+    void *xor_bits = NULL, *and_bits;
+    HICON16 handle = 0;
+
+    if (!pCreateIcon16 &&
+        !(pCreateIcon16 = (void *)GetProcAddress( GetModuleHandleA("user.exe16"), "CreateIcon16" )))
+        return 0;
+
+    if (!(GetIconInfo( icon, &info ))) return 0;
+    GetObjectW( info.hbmMask, sizeof(bm), &bm );
+    and_size = bm.bmHeight * bm.bmWidthBytes;
+    if (!(and_bits = HeapAlloc( GetProcessHeap(), 0, and_size ))) goto done;
+    GetBitmapBits( info.hbmMask, and_size, and_bits );
+    if (info.hbmColor)
+    {
+        GetObjectW( info.hbmColor, sizeof(bm), &bm );
+        xor_size = bm.bmHeight * bm.bmWidthBytes;
+        if (!(xor_bits = HeapAlloc( GetProcessHeap(), 0, xor_size ))) goto done;
+        GetBitmapBits( info.hbmColor, xor_size, xor_bits );
+    }
+    else
+    {
+        bm.bmHeight /= 2;
+        xor_bits = (char *)and_bits + and_size / 2;
+    }
+    handle = pCreateIcon16( inst, bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel,
+                            and_bits, xor_bits );
+done:
+    HeapFree( GetProcessHeap(), 0, and_bits );
+    if (info.hbmColor)
+    {
+        HeapFree( GetProcessHeap(), 0, xor_bits );
+        DeleteObject( info.hbmColor );
+    }
+    DeleteObject( info.hbmMask );
+    DestroyIcon( icon );
+    return handle;
+}
+
 /***********************************************************************
  * DllEntryPoint [SHELL.101]
  *
@@ -239,7 +282,7 @@ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
 	  if ((ret != 0xffffffff) && ret)
 	  {
 	    int i;
-	    for (i = 0; i < n; i++) RetPtr[i] = HICON_16(icons[i]);
+	    for (i = 0; i < n; i++) RetPtr[i] = convert_icon_to_16(hInstance, icons[i]);
 	  }
 	  else
 	  {
@@ -257,19 +300,18 @@ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
 HICON16 WINAPI ExtractIcon16( HINSTANCE16 hInstance, LPCSTR lpszExeFileName,
 	UINT16 nIconIndex )
 {   TRACE("\n");
-    return HICON_16(ExtractIconA(HINSTANCE_32(hInstance), lpszExeFileName, nIconIndex));
+    return convert_icon_to_16( hInstance, ExtractIconA(NULL, lpszExeFileName, nIconIndex) );
 }
 
 /*************************************************************************
  *             ExtractIconEx   (SHELL.40)
  */
-HICON16 WINAPI ExtractIconEx16(
+UINT16 WINAPI ExtractIconEx16(
 	LPCSTR lpszFile, INT16 nIconIndex, HICON16 *phiconLarge,
 	HICON16 *phiconSmall, UINT16 nIcons
 ) {
     HICON	*ilarge,*ismall;
-    UINT16	ret;
-    int		i;
+    int		i, ret;
 
     if (phiconLarge)
     	ilarge = HeapAlloc(GetProcessHeap(),0,nIcons*sizeof(HICON));
@@ -279,15 +321,15 @@ HICON16 WINAPI ExtractIconEx16(
     	ismall = HeapAlloc(GetProcessHeap(),0,nIcons*sizeof(HICON));
     else
     	ismall = NULL;
-    ret = HICON_16(ExtractIconExA(lpszFile,nIconIndex,ilarge,ismall,nIcons));
+    ret = ExtractIconExA(lpszFile,nIconIndex,ilarge,ismall,nIcons);
     if (ilarge) {
-    	for (i=0;i<nIcons;i++)
-	    phiconLarge[i]=HICON_16(ilarge[i]);
+	for (i=0;i<ret;i++)
+	    phiconLarge[i] = convert_icon_to_16(0, ilarge[i]);
 	HeapFree(GetProcessHeap(),0,ilarge);
     }
     if (ismall) {
-    	for (i=0;i<nIcons;i++)
-	    phiconSmall[i]=HICON_16(ismall[i]);
+	for (i=0;i<ret;i++)
+	    phiconSmall[i] = convert_icon_to_16(0, ismall[i]);
 	HeapFree(GetProcessHeap(),0,ismall);
     }
     return ret;
@@ -301,8 +343,7 @@ HICON16 WINAPI ExtractIconEx16(
  */
 HICON16 WINAPI ExtractAssociatedIcon16(HINSTANCE16 hInst, LPSTR lpIconPath, LPWORD lpiIcon)
 {
-    return HICON_16(ExtractAssociatedIconA(HINSTANCE_32(hInst), lpIconPath,
-		    lpiIcon));
+    return convert_icon_to_16( hInst, ExtractAssociatedIconA(NULL, lpIconPath, lpiIcon) );
 }
 
 /*************************************************************************




More information about the wine-cvs mailing list