Implemented Win95-style shared cursor/icon cache.

Merged NE and PE resource handling.
This commit is contained in:
Ulrich Weigand 1999-03-10 14:00:29 +00:00 committed by Alexandre Julliard
parent 82c70ad91e
commit 50a0915101
2 changed files with 309 additions and 294 deletions

View File

@ -69,11 +69,21 @@ typedef struct
#pragma pack(4) #pragma pack(4)
#define CID_RESOURCE 0x0001
#define CID_WIN32 0x0004
#define CID_NONSHARED 0x0008
extern void CURSORICON_Init( void );
extern HCURSOR16 CURSORICON_IconToCursor( HICON16 hIcon, extern HCURSOR16 CURSORICON_IconToCursor( HICON16 hIcon,
BOOL bSemiTransparent ); BOOL bSemiTransparent );
extern HGLOBAL CURSORICON_Load( HINSTANCE hInstance, LPCWSTR name, extern HGLOBAL CURSORICON_Load( HINSTANCE hInstance, LPCWSTR name,
int width, int height, int colors, int width, int height, int colors,
BOOL fCursor, UINT loadflags); BOOL fCursor, UINT loadflags);
extern WORD CURSORICON_Destroy( HGLOBAL16 handle, UINT16 flags );
extern void CURSORICON_FreeModuleIcons( HMODULE hModule );
#endif /* __WINE_CURSORICON_H */ #endif /* __WINE_CURSORICON_H */

View File

@ -53,6 +53,134 @@ static HCURSOR hActiveCursor = 0; /* Active cursor */
static INT CURSOR_ShowCount = 0; /* Cursor display count */ static INT CURSOR_ShowCount = 0; /* Cursor display count */
static RECT CURSOR_ClipRect; /* Cursor clipping rect */ static RECT CURSOR_ClipRect; /* Cursor clipping rect */
/**********************************************************************
* ICONCACHE for cursors/icons loaded with LR_SHARED.
*
* FIXME: This should not be allocated on the system heap, but on a
* subsystem-global heap (i.e. one for all Win16 processes,
* and one each for every Win32 process).
*/
typedef struct tagICONCACHE
{
struct tagICONCACHE *next;
HMODULE hModule;
HRSRC hRsrc;
HANDLE handle;
INT count;
} ICONCACHE;
static ICONCACHE *IconAnchor = NULL;
static CRITICAL_SECTION IconCrst;
/**********************************************************************
* CURSORICON_Init
*/
void CURSORICON_Init( void )
{
InitializeCriticalSection( &IconCrst );
MakeCriticalSectionGlobal( &IconCrst );
}
/**********************************************************************
* CURSORICON_FindSharedIcon
*/
static HANDLE CURSORICON_FindSharedIcon( HMODULE hModule, HRSRC hRsrc )
{
HANDLE handle = 0;
ICONCACHE *ptr;
EnterCriticalSection( &IconCrst );
for ( ptr = IconAnchor; ptr; ptr = ptr->next )
if ( ptr->hModule == hModule && ptr->hRsrc == hRsrc )
{
ptr->count++;
handle = ptr->handle;
break;
}
LeaveCriticalSection( &IconCrst );
return handle;
}
/**********************************************************************
* CURSORICON_AddSharedIcon
*/
static void CURSORICON_AddSharedIcon( HMODULE hModule, HRSRC hRsrc, HANDLE handle )
{
ICONCACHE *ptr = HeapAlloc( SystemHeap, 0, sizeof(ICONCACHE) );
if ( !ptr ) return;
ptr->hModule = hModule;
ptr->hRsrc = hRsrc;
ptr->handle = handle;
ptr->count = 1;
EnterCriticalSection( &IconCrst );
ptr->next = IconAnchor;
IconAnchor = ptr;
LeaveCriticalSection( &IconCrst );
}
/**********************************************************************
* CURSORICON_DelSharedIcon
*/
static INT CURSORICON_DelSharedIcon( HANDLE handle )
{
INT count = -1;
ICONCACHE *ptr;
EnterCriticalSection( &IconCrst );
for ( ptr = IconAnchor; ptr; ptr = ptr->next )
if ( ptr->handle == handle )
{
if ( ptr->count > 0 ) ptr->count--;
count = ptr->count;
break;
}
LeaveCriticalSection( &IconCrst );
return count;
}
/**********************************************************************
* CURSORICON_FreeModuleIcons
*/
void CURSORICON_FreeModuleIcons( HMODULE hModule )
{
ICONCACHE **ptr = &IconAnchor;
if ( HIWORD( hModule ) )
hModule = MapHModuleLS( hModule );
else
hModule = GetExePtr( hModule );
EnterCriticalSection( &IconCrst );
while ( *ptr )
{
if ( (*ptr)->hModule == hModule )
{
ICONCACHE *freePtr = *ptr;
*ptr = freePtr->next;
GlobalFree16( freePtr->handle );
HeapFree( SystemHeap, 0, freePtr );
continue;
}
ptr = &(*ptr)->next;
}
LeaveCriticalSection( &IconCrst );
}
/********************************************************************** /**********************************************************************
* CURSORICON_FindBestIcon * CURSORICON_FindBestIcon
* *
@ -299,73 +427,6 @@ fail:
return FALSE; return FALSE;
} }
/**********************************************************************
* CURSORICON_LoadDirEntry16
*
* Load the icon/cursor directory for a given resource name and find the
* best matching entry.
*/
static BOOL CURSORICON_LoadDirEntry16( HINSTANCE hInstance, SEGPTR name,
INT width, INT height, INT colors,
BOOL fCursor, CURSORICONDIRENTRY *dirEntry )
{
HRSRC16 hRsrc;
HGLOBAL16 hMem;
CURSORICONDIR *dir;
CURSORICONDIRENTRY *entry = NULL;
if (!(hRsrc = FindResource16( hInstance, name,
fCursor ? RT_GROUP_CURSOR16 : RT_GROUP_ICON16 )))
return FALSE;
if (!(hMem = LoadResource16( hInstance, hRsrc ))) return FALSE;
if ((dir = (CURSORICONDIR *)LockResource16( hMem )))
{
if (fCursor)
entry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor( dir,
width, height, 1);
else
entry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon( dir,
width, height, colors );
if (entry) *dirEntry = *entry;
}
FreeResource16( hMem );
return (entry != NULL);
}
/**********************************************************************
* CURSORICON_LoadDirEntry32
*
* Load the icon/cursor directory for a given resource name and find the
* best matching entry.
*/
static BOOL CURSORICON_LoadDirEntry( HINSTANCE hInstance, LPCWSTR name,
INT width, INT height, INT colors,
BOOL fCursor, CURSORICONDIRENTRY *dirEntry )
{
HANDLE hRsrc;
HANDLE hMem;
CURSORICONDIR *dir;
CURSORICONDIRENTRY *entry = NULL;
if (!(hRsrc = FindResourceW( hInstance, name,
fCursor ? RT_GROUP_CURSORW : RT_GROUP_ICONW )))
return FALSE;
if (!(hMem = LoadResource( hInstance, hRsrc ))) return FALSE;
if ((dir = (CURSORICONDIR*)LockResource( hMem )))
{
if (fCursor)
entry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor( dir,
width, height, 1);
else
entry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon( dir,
width, height, colors );
if (entry) *dirEntry = *entry;
}
FreeResource( hMem );
return (entry != NULL);
}
/********************************************************************** /**********************************************************************
* CURSORICON_CreateFromResource * CURSORICON_CreateFromResource
@ -598,148 +659,124 @@ HICON WINAPI CreateIconFromResourceEx( LPBYTE bits, UINT cbSize,
return 0; return 0;
} }
/********************************************************************** /**********************************************************************
* CURSORICON_Load16 * CURSORICON_Load
* *
* Load a cursor or icon from a 16-bit resource. * Load a cursor or icon from resource or file.
*/
static HGLOBAL16 CURSORICON_Load16( HINSTANCE16 hInstance, SEGPTR name,
INT width, INT height, INT colors,
BOOL fCursor, UINT loadflags)
{
HGLOBAL16 handle = 0;
HRSRC16 hRsrc;
CURSORICONDIRENTRY dirEntry;
if (!hInstance) /* OEM cursor/icon */
{
HDC hdc;
DC *dc;
if (HIWORD(name)) /* Check for '#xxx' name */
{
char *ptr = PTR_SEG_TO_LIN( name );
if (ptr[0] != '#') return 0;
if (!(name = (SEGPTR)atoi( ptr + 1 ))) return 0;
}
hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
dc = DC_GetDCPtr( hdc );
if(dc->funcs->pLoadOEMResource)
handle = dc->funcs->pLoadOEMResource( LOWORD(name), fCursor ?
OEM_CURSOR : OEM_ICON);
GDI_HEAP_UNLOCK( hdc );
DeleteDC( hdc );
return handle;
}
/* Find the best entry in the directory */
if ( !CURSORICON_LoadDirEntry16( hInstance, name, width, height,
colors, fCursor, &dirEntry ) ) return 0;
/* Load the resource */
if ( (hRsrc = FindResource16( hInstance,
MAKEINTRESOURCE16( dirEntry.icon.wResId ),
fCursor ? RT_CURSOR16 : RT_ICON16 )) )
{
/* 16-bit icon or cursor resources are processed
* transparently by the LoadResource16() via custom
* resource handlers set by SetResourceHandler().
*/
if ( (handle = LoadResource16( hInstance, hRsrc )) )
return handle;
}
return 0;
}
/**********************************************************************
* CURSORICON_Load32
*
* Load a cursor or icon from a 32-bit resource.
*/ */
HGLOBAL CURSORICON_Load( HINSTANCE hInstance, LPCWSTR name, HGLOBAL CURSORICON_Load( HINSTANCE hInstance, LPCWSTR name,
int width, int height, int colors, INT width, INT height, INT colors,
BOOL fCursor, UINT loadflags ) BOOL fCursor, UINT loadflags )
{ {
HANDLE handle = 0, h = 0; HANDLE handle = 0, h = 0;
HANDLE hRsrc; HANDLE hRsrc;
CURSORICONDIRENTRY dirEntry; CURSORICONDIR *dir;
CURSORICONDIRENTRY *dirEntry;
LPBYTE bits; LPBYTE bits;
if (!(loadflags & LR_LOADFROMFILE)) if ( loadflags & LR_LOADFROMFILE ) /* Load from file */
{ {
if (!hInstance) /* OEM cursor/icon */ LPBYTE *ptr;
{ if (!CURSORICON_SimulateLoadingFromResourceW((LPWSTR)name, fCursor, &dir, &ptr))
WORD resid; return 0;
HDC hdc; if (fCursor)
DC *dc; dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor(dir, width, height, 1);
else
dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(dir, width, height, colors);
bits = ptr[dirEntry->icon.wResId-1];
h = CURSORICON_CreateFromResource( 0, 0, bits, dirEntry->icon.dwBytesInRes,
!fCursor, 0x00030000, width, height, loadflags);
HeapFree( GetProcessHeap(), 0, dir );
HeapFree( GetProcessHeap(), 0, ptr );
}
if(HIWORD(name)) else if ( !hInstance ) /* Load OEM cursor/icon */
{
WORD resid;
HDC hdc;
DC *dc;
if ( HIWORD(name) )
{
LPSTR ansi = HEAP_strdupWtoA(GetProcessHeap(),0,name);
if( ansi[0]=='#') /*Check for '#xxx' name */
{ {
LPSTR ansi = HEAP_strdupWtoA(GetProcessHeap(),0,name); resid = atoi(ansi+1);
if( ansi[0]=='#') /*Check for '#xxx' name */ HeapFree( GetProcessHeap(), 0, ansi );
{ }
resid = atoi(ansi+1); else
HeapFree( GetProcessHeap(), 0, ansi ); {
} HeapFree( GetProcessHeap(), 0, ansi );
else return 0;
{
HeapFree( GetProcessHeap(), 0, ansi );
return 0;
}
} }
else resid = LOWORD(name);
hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
dc = DC_GetDCPtr( hdc );
if(dc->funcs->pLoadOEMResource)
handle = dc->funcs->pLoadOEMResource( resid, fCursor ?
OEM_CURSOR : OEM_ICON );
GDI_HEAP_UNLOCK( hdc );
DeleteDC( hdc );
return handle;
} }
else resid = LOWORD(name);
hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
dc = DC_GetDCPtr( hdc );
if (dc->funcs->pLoadOEMResource)
h = dc->funcs->pLoadOEMResource( resid, fCursor ?
OEM_CURSOR : OEM_ICON );
GDI_HEAP_UNLOCK( hdc );
DeleteDC( hdc );
}
else /* Load from resource */
{
WORD wResId;
DWORD dwBytesInRes;
/* Normalize hInstance (must be uniquely represented for icon cache) */
if ( HIWORD( hInstance ) )
hInstance = MapHModuleLS( hInstance );
else
hInstance = GetExePtr( hInstance );
/* Get directory resource ID */
if (!(hRsrc = FindResourceW( hInstance, name,
fCursor ? RT_GROUP_CURSORW : RT_GROUP_ICONW )))
return 0;
/* If shared icon, check whether it was already loaded */
if ( (loadflags & LR_SHARED)
&& (h = CURSORICON_FindSharedIcon( hInstance, hRsrc ) ) != 0 )
return h;
/* Find the best entry in the directory */ /* Find the best entry in the directory */
if (!CURSORICON_LoadDirEntry( hInstance, name, width, height, if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
colors, fCursor, &dirEntry ) ) return 0; if (!(dir = (CURSORICONDIR*)LockResource( handle ))) return 0;
if (fCursor)
dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor( dir,
width, height, 1);
else
dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon( dir,
width, height, colors );
if (!dirEntry) return 0;
wResId = dirEntry->icon.wResId;
dwBytesInRes = dirEntry->icon.dwBytesInRes;
FreeResource( handle );
/* Load the resource */ /* Load the resource */
if (!(hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(dirEntry.icon.wResId), if (!(hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(wResId),
fCursor ? RT_CURSORW : RT_ICONW ))) return 0; fCursor ? RT_CURSORW : RT_ICONW ))) return 0;
if (!(handle = LoadResource( hInstance, hRsrc ))) return 0; if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
/* Hack to keep LoadCursor/Icon32() from spawning multiple
* copies of the same object.
*/
#define pRsrcEntry ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)
if( pRsrcEntry->ResourceHandle ) return pRsrcEntry->ResourceHandle;
bits = (LPBYTE)LockResource( handle ); bits = (LPBYTE)LockResource( handle );
h = CURSORICON_CreateFromResource( 0, 0, bits, dirEntry.icon.dwBytesInRes, h = CURSORICON_CreateFromResource( 0, 0, bits, dwBytesInRes,
!fCursor, 0x00030000, width, height, loadflags); !fCursor, 0x00030000, width, height, loadflags);
pRsrcEntry->ResourceHandle = h; FreeResource( handle );
}
else
{
CURSORICONDIR *res;
LPBYTE *ptr;
if (!CURSORICON_SimulateLoadingFromResourceW((LPWSTR)name, fCursor, &res, &ptr))
return 0;
if (fCursor)
dirEntry = *(CURSORICONDIRENTRY *)CURSORICON_FindBestCursor(res, width, height, 1);
else
dirEntry = *(CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(res, width, height, colors);
bits = ptr[dirEntry.icon.wResId-1];
h = CURSORICON_CreateFromResource( 0, 0, bits, dirEntry.icon.dwBytesInRes,
!fCursor, 0x00030000, width, height, loadflags);
HeapFree( GetProcessHeap(), 0, res );
HeapFree( GetProcessHeap(), 0, ptr );
}
return h;
#undef pRsrcEntry
}
/* If shared icon, add to icon cache */
if ( h && (loadflags & LR_SHARED) )
CURSORICON_AddSharedIcon( hInstance, hRsrc, h );
}
return h;
}
/*********************************************************************** /***********************************************************************
* CURSORICON_Copy * CURSORICON_Copy
@ -846,7 +883,7 @@ HCURSOR16 CURSORICON_IconToCursor(HICON16 hIcon, BOOL bSemiTransparent)
if( !hRet ) /* fall back on default drag cursor */ if( !hRet ) /* fall back on default drag cursor */
hRet = CURSORICON_Copy( pTask->hInstance , hRet = CURSORICON_Copy( pTask->hInstance ,
CURSORICON_Load16(0,MAKEINTRESOURCE16(OCR_DRAGOBJECT), CURSORICON_Load(0,MAKEINTRESOURCEW(OCR_DRAGOBJECT),
SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE, 0) ); SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE, 0) );
} }
@ -859,15 +896,8 @@ HCURSOR16 CURSORICON_IconToCursor(HICON16 hIcon, BOOL bSemiTransparent)
*/ */
HCURSOR16 WINAPI LoadCursor16( HINSTANCE16 hInstance, SEGPTR name ) HCURSOR16 WINAPI LoadCursor16( HINSTANCE16 hInstance, SEGPTR name )
{ {
if (HIWORD(name)) LPCSTR nameStr = HIWORD(name)? PTR_SEG_TO_LIN(name) : (LPCSTR)name;
TRACE(cursor, "%04x '%s'\n", return LoadCursorA( hInstance, nameStr );
hInstance, (char *)PTR_SEG_TO_LIN( name ) );
else
TRACE(cursor, "%04x %04x\n",
hInstance, LOWORD(name) );
return CURSORICON_Load16( hInstance, name,
SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE, 0);
} }
@ -876,20 +906,8 @@ HCURSOR16 WINAPI LoadCursor16( HINSTANCE16 hInstance, SEGPTR name )
*/ */
HICON16 WINAPI LoadIcon16( HINSTANCE16 hInstance, SEGPTR name ) HICON16 WINAPI LoadIcon16( HINSTANCE16 hInstance, SEGPTR name )
{ {
HDC hdc = GetDC(0); LPCSTR nameStr = HIWORD(name)? PTR_SEG_TO_LIN(name) : (LPCSTR)name;
UINT palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL); return LoadIconA( hInstance, nameStr );
ReleaseDC(0, hdc);
if (HIWORD(name))
TRACE(icon, "%04x '%s'\n",
hInstance, (char *)PTR_SEG_TO_LIN( name ) );
else
TRACE(icon, "%04x %04x\n",
hInstance, LOWORD(name) );
return CURSORICON_Load16( hInstance, name,
SYSMETRICS_CXICON, SYSMETRICS_CYICON,
MIN(16, palEnts), FALSE, 0);
} }
@ -1016,65 +1034,76 @@ HCURSOR16 WINAPI CopyCursor16( HINSTANCE16 hInstance, HCURSOR16 hCursor )
return CURSORICON_Copy( hInstance, hCursor ); return CURSORICON_Copy( hInstance, hCursor );
} }
/**********************************************************************
* CURSORICON_Destroy (USER.610)
*
* This routine is actually exported from Win95 USER under the name
* DestroyIcon32 ... The behaviour implemented here should mimic
* the Win95 one exactly, especially the return values, which
* depend on the setting of various flags.
*/
WORD CURSORICON_Destroy( HGLOBAL16 handle, UINT16 flags )
{
WORD retv;
TRACE( icon, "(%04x, %04x)\n", handle, flags );
/* Check whether destroying active cursor */
if ( hActiveCursor == handle )
{
ERR( cursor, "Destroying active cursor!\n" );
SetCursor( 0 );
}
/* Try shared cursor/icon first */
if ( !(flags & CID_NONSHARED) )
{
INT count = CURSORICON_DelSharedIcon( handle );
if ( count != -1 )
return (flags & CID_WIN32)? TRUE : (count == 0);
/* FIXME: OEM cursors/icons should be recognized */
}
/* Now assume non-shared cursor/icon */
retv = GlobalFree16( handle );
return (flags & CID_RESOURCE)? retv : TRUE;
}
/*********************************************************************** /***********************************************************************
* DestroyIcon16 (USER.457) * DestroyIcon16 (USER.457)
*/ */
BOOL16 WINAPI DestroyIcon16( HICON16 hIcon ) BOOL16 WINAPI DestroyIcon16( HICON16 hIcon )
{ {
TRACE(icon, "%04x\n", hIcon ); return CURSORICON_Destroy( hIcon, 0 );
/* FIXME: should check for OEM/global heap icon here */
return (FreeResource16( hIcon ) == 0);
} }
/*********************************************************************** /***********************************************************************
* DestroyIcon32 (USER32.133) * DestroyIcon (USER32.133)
*/ */
BOOL WINAPI DestroyIcon( HICON hIcon ) BOOL WINAPI DestroyIcon( HICON hIcon )
{ {
TRACE(icon, "%04x\n", hIcon ); return CURSORICON_Destroy( hIcon, CID_WIN32 );
/* FIXME: should check for OEM/global heap icon here */
/* Unlike DestroyIcon16, only icons created with CreateIcon32
are valid for DestroyIcon32, so don't use FreeResource32 */
return (GlobalFree16( hIcon ) == 0);
} }
/*********************************************************************** /***********************************************************************
* DestroyCursor16 (USER.458) * DestroyCursor16 (USER.458)
*/ */
BOOL16 WINAPI DestroyCursor16( HCURSOR16 hCursor ) BOOL16 WINAPI DestroyCursor16( HCURSOR16 hCursor )
{ {
TRACE(cursor, "%04x\n", hCursor ); return CURSORICON_Destroy( hCursor, 0 );
if (FreeResource16( hCursor ) == 0)
return TRUE;
else
/* I believe this very same line should be added for every function
where appears the comment:
"FIXME: should check for OEM/global heap cursor here"
which are most (all?) the ones that call FreeResource, at least
in this module. Maybe this should go to a wrapper to avoid
repetition. Or: couldn't it go to FreeResoutce itself?
I'll let this to someone savvy on the subject.
*/
return (GlobalFree16 (hCursor) == 0);
} }
/*********************************************************************** /***********************************************************************
* DestroyCursor32 (USER32.132) * DestroyCursor (USER32.132)
*/ */
BOOL WINAPI DestroyCursor( HCURSOR hCursor ) BOOL WINAPI DestroyCursor( HCURSOR hCursor )
{ {
TRACE(cursor, "%04x\n", hCursor ); return CURSORICON_Destroy( hCursor, CID_WIN32 );
/* FIXME: should check for OEM/global heap cursor here */
/* Unlike DestroyCursor16, only cursors created with CreateCursor32
are valid for DestroyCursor32, so don't use FreeResource32 */
return (GlobalFree16( hCursor ) == 0);
} }
@ -1451,7 +1480,7 @@ HGLOBAL16 WINAPI LoadDIBIconHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRS
* the block size. See LoadProc() in 16-bit SDK for more. * the block size. See LoadProc() in 16-bit SDK for more.
*/ */
hMemObj = USER_CallDefaultRsrcHandler( hMemObj, hModule, hRsrc ); hMemObj = NE_DefResourceHandler( hMemObj, hModule, hRsrc );
if( hMemObj ) if( hMemObj )
{ {
LPBYTE bits = (LPBYTE)GlobalLock16( hMemObj ); LPBYTE bits = (LPBYTE)GlobalLock16( hMemObj );
@ -1469,7 +1498,7 @@ HGLOBAL16 WINAPI LoadDIBIconHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRS
*/ */
HGLOBAL16 WINAPI LoadDIBCursorHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc ) HGLOBAL16 WINAPI LoadDIBCursorHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
{ {
hMemObj = USER_CallDefaultRsrcHandler( hMemObj, hModule, hRsrc ); hMemObj = NE_DefResourceHandler( hMemObj, hModule, hRsrc );
if( hMemObj ) if( hMemObj )
{ {
LPBYTE bits = (LPBYTE)GlobalLock16( hMemObj ); LPBYTE bits = (LPBYTE)GlobalLock16( hMemObj );
@ -1494,49 +1523,39 @@ HICON16 WINAPI LoadIconHandler16( HGLOBAL16 hResource, BOOL16 bNew )
} }
/*********************************************************************** /***********************************************************************
* LoadCursorW (USER32.362) * LoadCursorW (USER32.362)
*/ */
HCURSOR WINAPI LoadCursorW(HINSTANCE hInstance, LPCWSTR name) HCURSOR WINAPI LoadCursorW(HINSTANCE hInstance, LPCWSTR name)
{ {
return CURSORICON_Load( hInstance, name, return LoadImageW( hInstance, name, IMAGE_CURSOR, 0, 0,
SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE, 0); LR_SHARED | LR_DEFAULTSIZE );
} }
/*********************************************************************** /***********************************************************************
* LoadCursorA (USER32.359) * LoadCursorA (USER32.359)
*/ */
HCURSOR WINAPI LoadCursorA(HINSTANCE hInstance, LPCSTR name) HCURSOR WINAPI LoadCursorA(HINSTANCE hInstance, LPCSTR name)
{ {
HCURSOR res=0; return LoadImageA( hInstance, name, IMAGE_CURSOR, 0, 0,
if(!HIWORD(name)) LR_SHARED | LR_DEFAULTSIZE );
return LoadCursorW(hInstance,(LPCWSTR)name);
else
{
LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
res = LoadCursorW(hInstance, uni);
HeapFree( GetProcessHeap(), 0, uni);
}
return res;
}
/***********************************************************************
* LoadCursorFromFile32W (USER32.361)
*/
HCURSOR WINAPI LoadCursorFromFileW (LPCWSTR name)
{
return LoadImageW(0, name, IMAGE_CURSOR, SYSMETRICS_CXCURSOR,
SYSMETRICS_CYCURSOR, LR_LOADFROMFILE);
} }
/*********************************************************************** /***********************************************************************
* LoadCursorFromFile32A (USER32.360) * LoadCursorFromFileW (USER32.361)
*/
HCURSOR WINAPI LoadCursorFromFileW (LPCWSTR name)
{
return LoadImageW( 0, name, IMAGE_CURSOR, 0, 0,
LR_LOADFROMFILE | LR_DEFAULTSIZE );
}
/***********************************************************************
* LoadCursorFromFileA (USER32.360)
*/ */
HCURSOR WINAPI LoadCursorFromFileA (LPCSTR name) HCURSOR WINAPI LoadCursorFromFileA (LPCSTR name)
{ {
HCURSOR hcur; return LoadImageA( 0, name, IMAGE_CURSOR, 0, 0,
LPWSTR u_name = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); LR_LOADFROMFILE | LR_DEFAULTSIZE );
hcur = LoadCursorFromFileW(u_name);
HeapFree( GetProcessHeap(), 0, u_name );
return hcur;
} }
/*********************************************************************** /***********************************************************************
@ -1544,13 +1563,8 @@ HCURSOR WINAPI LoadCursorFromFileA (LPCSTR name)
*/ */
HICON WINAPI LoadIconW(HINSTANCE hInstance, LPCWSTR name) HICON WINAPI LoadIconW(HINSTANCE hInstance, LPCWSTR name)
{ {
HDC hdc = GetDC(0); return LoadImageW( hInstance, name, IMAGE_ICON, 0, 0,
UINT palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL); LR_SHARED | LR_DEFAULTSIZE );
ReleaseDC(0, hdc);
return CURSORICON_Load( hInstance, name,
SYSMETRICS_CXICON, SYSMETRICS_CYICON,
MIN( 16, palEnts ), FALSE, 0);
} }
/*********************************************************************** /***********************************************************************
@ -1558,17 +1572,8 @@ HICON WINAPI LoadIconW(HINSTANCE hInstance, LPCWSTR name)
*/ */
HICON WINAPI LoadIconA(HINSTANCE hInstance, LPCSTR name) HICON WINAPI LoadIconA(HINSTANCE hInstance, LPCSTR name)
{ {
HICON res=0; return LoadImageA( hInstance, name, IMAGE_ICON, 0, 0,
LR_SHARED | LR_DEFAULTSIZE );
if( !HIWORD(name) )
return LoadIconW(hInstance, (LPCWSTR)name);
else
{
LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
res = LoadIconW( hInstance, uni );
HeapFree( GetProcessHeap(), 0, uni );
}
return res;
} }
/********************************************************************** /**********************************************************************