diff --git a/dlls/shell.dll16/Makefile.in b/dlls/shell.dll16/Makefile.in index 8dff0a9602c..36b23fc3cd2 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 b8d99fd6bf9..be8ffeb8170 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