Release 960818
Sun Aug 18 12:17:54 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [files/drive.c]
Added 'Filesystem' option in drives configuration.
* [files/dos_fs.c]
Added handling of case-insensitive filesystems.
* [memory/selector.c] [include/stackframe.h]
Removed MAKE_SEGPTR.
* [misc/commdlg.c] [multimedia/mcistring.c]
Replaced MAKE_SEGPTR by the SEGPTR_* macros.
* [objects/bitblt.c] [windows/graphics.c]
Use an intermediary pixmap to avoid some BadMatch errors on
XGetImage().
Sun Aug 18 09:21:27 1996 Albrecht Kleine <kleine@ak.sax.de>
* [windows/message.c]
Added handling of WM_NC...mouse messages in JOURNALRECORD hook.
* [misc/ver.c]
Fixed a bad string result in VerQueryValue[16|32A|32W].
Fri Aug 16 19:55:04 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [if1632/crtdll.spec] [misc/crtdll.c]
More additions to get win95 programs further down the road.
* [if1632/kernel.spec] [loader/module.c]
GetModuleName() added.
LoadModule(): params->showCmd can be NULL.
* [if1632/kernel32.spec] [if1632/thunk.c]
ThunkConnect32() stub added.
* [loader/resource.c]
Entries include lastentry.
* [misc/shell.c] [files/file.c]
Made progman work again.
Fri Aug 16 09:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [windows/defwnd.c] [windows/winpos.c] [windows/painting.c]
Icon painting fixes.
* [windows/winpos.c] [windows/painting.c]
Enforce and follow hrgnUpdate more closely to cut down on
redundant RedrawWindow() calls.
* [windows/event.c]
Process ConfigureNotify only for managed windows.
* [windows/winpos.c]
Do not redraw parent if the window was hidden before SetWindowPos().
* [windows/nonclient.c]
Omit some nonclient decoration painting for managed windows.
* [controls/menu.c] [windows/mdi.c] [windows/nonclient.c]
Implemented WM_NEXTMENU.
* [controls/listbox.c]
Multicolumn listboxes return WVR_VREDRAW on WM_NCCALCSIZE.
* [misc/shell.c]
Added .ICO file handling to ExtractIcon().
diff --git a/misc/shell.c b/misc/shell.c
index 0f146e1..dd7aa3b 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -14,11 +14,38 @@
#include "resource.h"
#include "dlgs.h"
#include "win.h"
+#include "cursoricon.h"
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"
#include "winreg.h"
+/* .ICO file ICONDIR definitions */
+
+#pragma pack(1)
+
+typedef struct
+{
+ BYTE bWidth; /* Width, in pixels, of the image */
+ BYTE bHeight; /* Height, in pixels, of the image */
+ BYTE bColorCount; /* Number of colors in image (0 if >=8bpp) */
+ BYTE bReserved; /* Reserved ( must be 0) */
+ WORD wPlanes; /* Color Planes */
+ WORD wBitCount; /* Bits per pixel */
+ DWORD dwBytesInRes; /* How many bytes in this resource? */
+ DWORD dwImageOffset; /* Where in the file is this image? */
+} icoICONDIRENTRY, *LPicoICONDIRENTRY;
+
+typedef struct
+{
+ WORD idReserved; /* Reserved (must be 0) */
+ WORD idType; /* Resource Type (1 for icons) */
+ WORD idCount; /* How many images? */
+ icoICONDIRENTRY idEntries[1]; /* An entry for each image (idCount of 'em) */
+} icoICONDIR, *LPicoICONDIR;
+
+#pragma pack(4)
+
extern HANDLE CURSORICON_LoadHandler( HANDLE, HINSTANCE, BOOL);
extern WORD GetIconID( HANDLE hResource, DWORD resType );
@@ -124,7 +151,7 @@
HINSTANCE retval=31; /* default - 'No association was found' */
char *tok; /* token pointer */
int i; /* random counter */
- char xlpFile[256]; /* result of SearchPath */
+ char xlpFile[256]; /* result of SearchPath */
dprintf_exec(stddeb, "SHELL_FindExecutable: File %s, Dir %s\n",
(lpFile != NULL?lpFile:"-"),
@@ -140,6 +167,10 @@
}
if (SearchPath32A(lpDirectory,lpFile,NULL,sizeof(xlpFile),xlpFile,NULL))
lpFile = xlpFile;
+ else {
+ if (SearchPath32A(lpDirectory,lpFile,".exe",sizeof(xlpFile),xlpFile,NULL))
+ lpFile = xlpFile;
+ }
/* First thing we need is the file's extension */
extension = strrchr( xlpFile, '.' ); /* Assume last "." is the one; */
@@ -376,7 +407,7 @@
*
* FIXME: Implement GetPEResourceTable in w32sys.c and call it here.
*/
-BYTE* SHELL_GetResourceTable(HFILE hFile)
+static BYTE* SHELL_GetResourceTable(HFILE hFile)
{
struct mz_header_s mz_header;
struct ne_header_s ne_header;
@@ -391,7 +422,7 @@
return NULL;
if (ne_header.ne_magic == PE_SIGNATURE)
- { fprintf(stdnimp,"Win32 FIXME: file %s line %i\n", __FILE__, __LINE__ );
+ { fprintf(stdnimp,"Win32s FIXME: file %s line %i\n", __FILE__, __LINE__ );
return NULL; }
if (ne_header.ne_magic != NE_SIGNATURE) return NULL;
@@ -417,7 +448,7 @@
/*************************************************************************
* SHELL_LoadResource
*/
-HANDLE SHELL_LoadResource(HINSTANCE hInst, HFILE hFile, NE_NAMEINFO* pNInfo, WORD sizeShift)
+static HANDLE SHELL_LoadResource(HINSTANCE hInst, HFILE hFile, NE_NAMEINFO* pNInfo, WORD sizeShift)
{
BYTE* ptr;
HANDLE handle = DirectResAlloc( hInst, 0x10, (DWORD)pNInfo->length << sizeShift);
@@ -432,6 +463,74 @@
}
/*************************************************************************
+ * ICO_LoadIcon
+ */
+static HANDLE ICO_LoadIcon(HINSTANCE hInst, HFILE hFile, LPicoICONDIRENTRY lpiIDE)
+{
+ BYTE* ptr;
+ HANDLE handle = DirectResAlloc( hInst, 0x10, lpiIDE->dwBytesInRes);
+
+ if( (ptr = (BYTE*)GlobalLock16( handle )) )
+ {
+ _llseek( hFile, lpiIDE->dwImageOffset, SEEK_SET);
+ FILE_Read( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
+ return handle;
+ }
+ return (HANDLE)0;
+}
+
+/*************************************************************************
+ * ICO_GetIconDirectory
+ *
+ * Read .ico file and build phony ICONDIR struct for GetIconID
+ */
+static HANDLE ICO_GetIconDirectory(HINSTANCE hInst, HFILE hFile, LPicoICONDIR* lplpiID )
+{
+ WORD id[3]; /* idReserved, idType, idCount */
+ LPicoICONDIR lpiID;
+ int i;
+
+ _llseek( hFile, 0, SEEK_SET );
+ if( FILE_Read(hFile,(char*)id,sizeof(id)) != sizeof(id) ) return 0;
+
+ /* check .ICO header
+ *
+ * - see http://www.microsoft.com/win32dev/ui/icons.htm
+ */
+
+ if( id[0] || id[1] != 1 || !id[2] ) return 0;
+
+ i = id[2]*sizeof(icoICONDIRENTRY) + sizeof(id);
+
+ lpiID = (LPicoICONDIR)xmalloc(i);
+
+ if( FILE_Read(hFile,(char*)lpiID->idEntries,i) == i )
+ {
+ HANDLE handle = DirectResAlloc( hInst, 0x10,
+ id[2]*sizeof(ICONDIRENTRY) + sizeof(id) );
+ if( handle )
+ {
+ CURSORICONDIR* lpID = (CURSORICONDIR*)GlobalLock16( handle );
+ lpID->idReserved = lpiID->idReserved = id[0];
+ lpID->idType = lpiID->idType = id[1];
+ lpID->idCount = lpiID->idCount = id[2];
+ for( i=0; i < lpiID->idCount; i++ )
+ {
+ memcpy((void*)(lpID->idEntries + i),
+ (void*)(lpiID->idEntries + i), sizeof(ICONDIRENTRY) - 2);
+ lpID->idEntries[i].icon.wResId = i;
+ }
+ *lplpiID = lpiID;
+ return handle;
+ }
+ }
+ /* fail */
+
+ free(lpiID);
+ return 0;
+}
+
+/*************************************************************************
* InternalExtractIcon [SHELL.39]
*
* This abortion is called directly by Progman
@@ -449,79 +548,87 @@
if( hFile == HFILE_ERROR || !n ) return 0;
- hRet = GlobalAlloc16( GMEM_FIXED, sizeof(HICON16)*n);
+ hRet = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(HICON16)*n);
RetPtr = (HICON16*)GlobalLock16(hRet);
*RetPtr = (n == 0xFFFF)? 0: 1; /* error return values */
pData = SHELL_GetResourceTable(hFile);
if( pData )
+ {
+ HICON16 hIcon = 0;
+ BOOL icoFile = FALSE;
+ UINT iconDirCount = 0;
+ UINT iconCount = 0;
+ NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2);
+ NE_NAMEINFO* pIconStorage = NULL;
+ NE_NAMEINFO* pIconDir = NULL;
+ LPicoICONDIR lpiID = NULL;
+
if( pData == (BYTE*)-1 )
{
- /* FIXME: possible .ICO file */
+ /* check for .ICO file */
- fprintf(stddeb,"InternalExtractIcon: cannot handle file %s\n", lpszExeFileName);
+ hIcon = ICO_GetIconDirectory(hInstance, hFile, &lpiID);
+ if( hIcon )
+ { icoFile = TRUE; iconDirCount = 1; iconCount = lpiID->idCount; }
}
- else /* got resource table */
+ else while( pTInfo->type_id && !(pIconStorage && pIconDir) )
{
- UINT iconDirCount = 0;
- UINT iconCount = 0;
- NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2);
- NE_NAMEINFO* pIconStorage = NULL;
- NE_NAMEINFO* pIconDir = NULL;
-
/* find icon directory and icon repository */
- while( pTInfo->type_id && !(pIconStorage && pIconDir) )
+ if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON )
{
- if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON )
- {
- iconDirCount = pTInfo->count;
- pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
- dprintf_reg(stddeb,"\tfound directory - %i icon families\n", iconDirCount);
- }
- if( pTInfo->type_id == NE_RSCTYPE_ICON )
- {
- iconCount = pTInfo->count;
- pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
- dprintf_reg(stddeb,"\ttotal icons - %i\n", iconCount);
- }
- pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
- }
-
- /* load resources and create icons */
-
- if( pIconStorage && pIconDir )
-
- if( nIconIndex == (UINT)-1 ) RetPtr[0] = iconDirCount;
- else if( nIconIndex < iconDirCount )
- {
- HICON16 hIcon;
- UINT i, icon;
-
- if( n > iconDirCount - nIconIndex ) n = iconDirCount - nIconIndex;
-
- for( i = nIconIndex; i < nIconIndex + n; i++ )
- {
- hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i,
- *(WORD*)pData );
- RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
- GlobalFree16(hIcon);
- }
-
- for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
- {
- hIcon = 0;
- for( i = 0; i < iconCount; i++ )
- if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
- hIcon = SHELL_LoadResource( hInstance, hFile, pIconStorage + i,
- *(WORD*)pData );
- RetPtr[icon-nIconIndex] = (hIcon)?CURSORICON_LoadHandler( hIcon, hInstance, FALSE ):0;
- }
- }
- free(pData);
+ iconDirCount = pTInfo->count;
+ pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
+ dprintf_reg(stddeb,"\tfound directory - %i icon families\n", iconDirCount);
+ }
+ if( pTInfo->type_id == NE_RSCTYPE_ICON )
+ {
+ iconCount = pTInfo->count;
+ pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
+ dprintf_reg(stddeb,"\ttotal icons - %i\n", iconCount);
+ }
+ pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
}
+ /* load resources and create icons */
+
+ if( (pIconStorage && pIconDir) || icoFile )
+ if( nIconIndex == (UINT)-1 ) RetPtr[0] = iconDirCount;
+ else if( nIconIndex < iconDirCount )
+ {
+ UINT i, icon;
+
+ if( n > iconDirCount - nIconIndex ) n = iconDirCount - nIconIndex;
+
+ for( i = nIconIndex; i < nIconIndex + n; i++ )
+ {
+ /* .ICO files have only one icon directory */
+
+ if( !icoFile )
+ hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i,
+ *(WORD*)pData );
+ RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
+ GlobalFree16(hIcon);
+ }
+
+ for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
+ {
+ hIcon = 0;
+ if( icoFile )
+ hIcon = ICO_LoadIcon( hInstance, hFile, lpiID->idEntries + RetPtr[icon-nIconIndex]);
+ else
+ for( i = 0; i < iconCount; i++ )
+ if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
+ hIcon = SHELL_LoadResource( hInstance, hFile, pIconStorage + i,
+ *(WORD*)pData );
+ RetPtr[icon-nIconIndex] = (hIcon)?CURSORICON_LoadHandler( hIcon, hInstance, FALSE ):0;
+ }
+ }
+ if( icoFile ) free(lpiID);
+ else free(pData);
+ }
_lclose( hFile );
/* return array with icon handles */