Sun Feb 18 16:35:54 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [controls/desktop.c] Look for the wallpaper file in the Windows directory. * [controls/menu.c] Fixed swapped parameters in SetMenuItemBitmaps(). Create a separator in MENU_SetItemData() when the string is NULL. * [file/dosfs.c] DOSFS_FindNext: don't return '.' and '..' in a drive root dir. * [files/file.c] Added a DOS_FILE structure to store per-file information (not really used yet). Fixed _lread and _hread to check the size of the buffer before calling Unix read() to avoid EFAULT error. * [misc/exec.c] Return TRUE in WinHelp() for HELP_QUIT to quiet Notepad on exit. * [miscemu/instr.c] Call DOSMEM_Alarm() in INSTR_ReplaceSelector(). This should fix programs that poll the BIOS counter, provided they reload the selector on every read. * [miscemu/int21.c] Re-implemented FindFirst/FindNext for FCB calls. * [windows/message.c] [windows/winpos.c] Merged MSG_GetWindowForEvent() and WINPOS_WindowFromPoint(). * [windows/nonclient.c] [windows/win.c] [include/windows.h] Added a per-window WIN_MANAGED flag; only windows that have a dialog frame or a sizing border are managed. Sat Feb 17 18:25:00 1996 Thomas Sandford <tdgsandf@prds-grn.demon.co.uk> * [if1632/Makefile.in] Added -g flag to compilation of .c files generated from *32.spec. * [if1632/gdi32.spec] Numerous additional functions implemented. * if1632/user32.spec] wsprintfA maps to vsprintf not wsprintf Numerous additional functions implemented. * [include/gdi.h] [objects/gdiobj.c] New #define MAGIC_DONTCARE added. This is used in GDI_GetObjPtr to enable getting a pointer to a GDI object of unknow type. * [win32/gdi32.c] New file. * [win32/param32.c] WIN32_MoveToEx() - handle NULL pointer argument. * [win32/user32.c] USER32_InvalidateRect - handle passing of a NULL pointer. USER32_SetTimer - New function. * [files/directory.c] Fixed DIR_Init() (off by one in allocation of space for environment variables). * [files/drive.c] Added <sys/types.h> to #includes (prerequisite for <sys/stat.h> on FreeBSD). Fri Feb 16 10:26:56 1996 Andreas Kirschbaum <ank@rbg.informatik.th-darmstadt.de> * [controls/menu.c] Memory leak plugged. * [controls/edit.c] Erase space with function ExtTextOut(). This eliminates the use of xmalloc(). Memory leak in EDIT_WriteText plugged. * [debugger/db_disasm.c] Operand for scas now is di. * [files/profile.c] PROFILE_GetSection was copying too much data. PROFILE_GetSection now returns the correct value. It was returning the number of unused instead of used bytes. * [objects/dc.c] Corrected two typos in comments. * [objects/font.c] FONT_MatchFont didn't return if it couldn't find any font. * [objects/oembitmap.c] Free object only if it has been allocated. * [windows/scroll.c] Memory leak in ScrollDC plugged. Tue Feb 13 11:17:00 1996 William Magro <wmagro@tc.cornell.edu> * [controls/edit.c] Implemented ES_NOHIDESEL style, shift+click selection, shift+{arrow,home,end,pgup,pgdn} selection. Optimized (de)selection drawing. Changed selection drawing to use correct system colors instead of inverting. Fixed deleting or backspacing across a '\r\n' end of line pair. Selection now anchors correctly. Fixed text leaking and extra garbage problem bug uncovered by change in class style in wine960131. * [controls/widgets.c] Class flags now match those of Windows. Mon Feb 12 21:28:19 1996 Martin von Loewis <loewis@informatik.hu-berlin.de> * [controls/widgets.c] WIDGETS_Init: RELAY32_GetEntryPoint does not take a string anymore. * [if1632/Makefile.in][if1632/relay32.c][include/relay32.h] comctl32.spec ole32.spec winspool.spec: new files. RELAY32_Init: call initialization of new DLLs. RELAY32_GetEntryPoint: expects WIN32_builtin* now. RELAY32_MakeFakeModule: new function. * [if1632/gdi32.spec][if1632/kernel32.spec][if1632/user32.spec] Added Win95 functions. Ordinals now differ from both NT and Win95 HeapCreate, CreateDialogIndirectParamA, CreateDialogIndirectParamW, CreateDialogParamA, CreateDialogParamW, DialogBoxIndirectParamA DialogBoxIndirectParamW, DialogBoxParamA, DialogBoxParamW: new relays. * [if1632/shell32.spec] shell32.spec: renumbered all functions to take into account ordinals. These seem to be identical between NT and Win95. * [include/dialog.h][windows/dialog.c] xBaseUnit,yBaseUnit,DIALOG_DoDialogBox: made non-static. * [include/handle32.h] New handle types VRANGE, HEAP, HEAPITEM. * [include/pe_image.h][loader/pe_image.c] struct w_files: new field builtin. PE_FindExportedFunction: support ordinals. PE_GetProcAddress: call RELAY32_GetEntryPoint for builtins. fixup_imports: support ordinals. PE_LoadImage: prefer directories over segments. * [include/resource.h][win32/resource.c] FindResource32: changed parameter from LPCTSTR to LPCWSTR check LANG_NEUTRAL if LANG_ENGLISH fails. LoadAcceleratorsW,SizeofResource32,AccessResource32: disabled because it's broken. Casted to and from LPWSTR at various places. * [include/string32.h][win32/string32.c] Changed prototypes to take const arguments where appropriate. * [include/struct32.h] New structures DLGTEMPLATE32, DLGITEMTEMPLATE32. * [tools/build.c] BuildSpec32Files: generate Base value into code, generate call to RELAY32_MakeFakeModule. * [win32/heap.c] This is still not finished and needs rework. HeapAlloc: renamed to SIMPLE_HeapAlloc, implemented HeapAlloc. HeapCreate: implemented on top of VirtualAlloc, which does not work yet HeapDestroy, HEAP_GrowHeap, HeapFree: new functions. * [win32/memory.c] Support for VRANGE_OBJECT. This is not yet called from any place, and needs more platform specific support MEMORY_FindVrange, MEMORY_IsVrangeFree, MEMORY_InsertVrange, MEMORY_AllocVrange, MEMORY_ReleaseVrange: new functions. * [win32/user32.c] WIN32_CreateWindowExA: don't GlobalAlloc for integer class and window names, as in dialogs. Implemented dialog functions (see user32.spec). * [windows/caret.c] CARET_Initialize: call RELAY32_GetBuiltinDLL. Mon Feb 12 18:52:40 1996 Jim Peterson <jspeter@birch.ee.vt.edu> * [controls/edit.c] Removed commented out #ifdefs for WINELIB. * [tools/makehtml.pl] Put in error checking when trying to open a file. * [libtest/Makefile.in] [libtest/new.c] [libtest/hello4.c] Added two new targets: hello4 and new. * [include/windows.h] Added definition of DEVMODE structure, although it's not yet used. Modified various API functions from CreateDC() to Escape(), in order to make them more compliant with the strict API definitions. * [include/wintypes.h] Added 'typedef char TCHAR'. It probably should be defined as 'short', but then we would have to support such characters. Also did 'typedef const TCHAR* LPCTSTR' and 'typedef TCHAR* LPTSTR'. Also defined WNDENUMPROC, FONTENUMPROC, GOBJENUMPROC, PROPENUMPROC MFENUMPROC, and HGDIOBJ. Mon Feb 5 16:42:07 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl> * [misc/commdlg.c] Patched a bug that occurred in the internal COMMDLG module for the FileOpen(), FileSave() and FileSaveAs() functions. The file-type combobox is now handled correctly. Fri Feb 2 22:52:58 1996 Roman Dolejsi <roman@sorry.vse.cz> * [resources/sysres_Cz.rc] Added support for Czech [Cz] language. Thu Feb 1 00:35:04 1996 Philippe De Muyter <phdm@info.ucl.ac.be> * [objects/font.c] FONT_matchfont : for fixed-spacing fonts, allow 'c' if 'm' fails; for variable-spacing fonts : allow '*' if 'p' fails; if asked lfHeight is -1, assume 0. CreateFontIndirect : if font parameter is NULL, issue an error message. CreateFont : null-terminate lfFaceName. ParseFontParms : debug code turned off : too verbose. InitFontsList : recognize *-c-* fonts as fixed-spacing fonts. * [objects/color.c] ColorToPhysical : admit 0xff...... COLORREF's as 0x00...... ones.
465 lines
13 KiB
C
465 lines
13 KiB
C
/*
|
||
* Win32 Resources
|
||
*
|
||
* Copyright 1995 Thomas Sandford
|
||
* Copyright 1996 Martin von Loewis
|
||
*
|
||
* Based on the Win16 resource handling code in loader/resource.c
|
||
* Copyright 1993 Robert J. Amstadt
|
||
* Copyright 1995 Alexandre Julliard
|
||
*
|
||
* This is not even at ALPHA level yet. Don't expect it to work!
|
||
*/
|
||
|
||
#include <sys/types.h>
|
||
#include "wintypes.h"
|
||
#include "windows.h"
|
||
#include "kernel32.h"
|
||
#include "pe_image.h"
|
||
#include "handle32.h"
|
||
#include "libres.h"
|
||
#include "resource32.h"
|
||
#include "stackframe.h"
|
||
#include "neexe.h"
|
||
#include "accel.h"
|
||
#include "xmalloc.h"
|
||
#include "string32.h"
|
||
#include "stddebug.h"
|
||
#include "debug.h"
|
||
|
||
int language = 0x0409;
|
||
|
||
#if 0
|
||
#define PrintId(name) \
|
||
if (HIWORD((DWORD)name)) \
|
||
dprintf_resource( stddeb, "'%s'", name); \
|
||
else \
|
||
dprintf_resource( stddeb, "#%04x", LOWORD(name));
|
||
#else
|
||
#define PrintId(name)
|
||
#endif
|
||
|
||
/**********************************************************************
|
||
* GetResDirEntry
|
||
*
|
||
* Helper function - goes down one level of PE resource tree
|
||
*
|
||
*/
|
||
PIMAGE_RESOURCE_DIRECTORY GetResDirEntry(PIMAGE_RESOURCE_DIRECTORY resdirptr,
|
||
LPCWSTR name,
|
||
DWORD root)
|
||
{
|
||
int entrynum;
|
||
PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
|
||
int namelen;
|
||
|
||
if (HIWORD(name)) {
|
||
/* FIXME: what about #xxx names? */
|
||
entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
|
||
(BYTE *) resdirptr +
|
||
sizeof(IMAGE_RESOURCE_DIRECTORY));
|
||
namelen = STRING32_lstrlenW(name);
|
||
for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
|
||
{
|
||
PIMAGE_RESOURCE_DIR_STRING_U str =
|
||
(PIMAGE_RESOURCE_DIR_STRING_U) (root +
|
||
(entryTable[entrynum].Name & 0x7fffffff));
|
||
if(namelen != str->Length)
|
||
continue;
|
||
if(STRING32_lstrcmpniW(name,str->NameString,str->Length)==0)
|
||
return (PIMAGE_RESOURCE_DIRECTORY) (
|
||
root +
|
||
(entryTable[entrynum].OffsetToData & 0x7fffffff));
|
||
}
|
||
return NULL;
|
||
} else {
|
||
entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
|
||
(BYTE *) resdirptr +
|
||
sizeof(IMAGE_RESOURCE_DIRECTORY) +
|
||
resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
|
||
for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
|
||
if ((DWORD)entryTable[entrynum].Name == (DWORD)name)
|
||
return (PIMAGE_RESOURCE_DIRECTORY) (
|
||
root +
|
||
(entryTable[entrynum].OffsetToData & 0x7fffffff));
|
||
return NULL;
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* FindResource (KERNEL.60)
|
||
*/
|
||
HANDLE32 FindResource32( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
|
||
{
|
||
#ifndef WINELIB
|
||
struct w_files *wptr = wine_files;
|
||
PIMAGE_RESOURCE_DIRECTORY resdirptr;
|
||
DWORD root;
|
||
HANDLE32 result;
|
||
|
||
#if 0
|
||
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
|
||
#endif
|
||
dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
|
||
PrintId( type );
|
||
dprintf_resource( stddeb, " name=" );
|
||
PrintId( name );
|
||
dprintf_resource( stddeb, "\n" );
|
||
while (wptr != NULL && (wptr->hModule != hModule))
|
||
wptr = wptr->next;
|
||
if ((wptr == NULL) || (wptr->pe == NULL) || (wptr->pe->pe_resource == NULL))
|
||
return 0;
|
||
resdirptr = (PIMAGE_RESOURCE_DIRECTORY) wptr->pe->pe_resource;
|
||
root = (DWORD) resdirptr;
|
||
if ((resdirptr = GetResDirEntry(resdirptr, type, root)) == NULL)
|
||
return 0;
|
||
if ((resdirptr = GetResDirEntry(resdirptr, name, root)) == NULL)
|
||
return 0;
|
||
result = GetResDirEntry(resdirptr, (LPCWSTR)language, root);
|
||
/* Try LANG_NEUTRAL, too */
|
||
if(!result)
|
||
return GetResDirEntry(resdirptr, (LPCWSTR)0, root);
|
||
#else
|
||
return LIBRES_FindResource( hModule, name, type );
|
||
#endif
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* LoadResource (KERNEL.61)
|
||
*/
|
||
HANDLE32 LoadResource32( HINSTANCE hModule, HANDLE32 hRsrc )
|
||
{
|
||
#ifndef WINELIB
|
||
struct w_files *wptr = wine_files;
|
||
|
||
#if 0
|
||
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
|
||
#endif
|
||
dprintf_resource(stddeb, "LoadResource: module="NPFMT" res="NPFMT"\n",
|
||
hModule, hRsrc );
|
||
if (!hRsrc) return 0;
|
||
while (wptr != NULL && (wptr->hModule != hModule))
|
||
wptr = wptr->next;
|
||
if ((wptr == NULL) || (wptr->pe == NULL) || (wptr->pe->pe_resource == NULL))
|
||
return 0;
|
||
return (HANDLE32) (wptr->load_addr+((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
|
||
#else
|
||
return LIBRES_LoadResource( hModule, hRsrc );
|
||
#endif
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* LockResource (KERNEL.62)
|
||
*/
|
||
LPVOID LockResource32( HANDLE32 handle )
|
||
{
|
||
return (LPVOID) handle;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* FreeResource (KERNEL.63)
|
||
*/
|
||
BOOL FreeResource32( HANDLE32 handle )
|
||
{
|
||
/* no longer used in Win32 */
|
||
return TRUE;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* AccessResource (KERNEL.64)
|
||
*/
|
||
INT AccessResource32( HINSTANCE hModule, HRSRC hRsrc )
|
||
{
|
||
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
|
||
dprintf_resource(stddeb, "AccessResource: module="NPFMT" res="NPFMT"\n",
|
||
hModule, hRsrc );
|
||
if (!hRsrc) return 0;
|
||
fprintf(stderr,"AccessResource32: not implemented\n");
|
||
return 0;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* SizeofResource (KERNEL.65)
|
||
*/
|
||
DWORD SizeofResource32( HINSTANCE hModule, HRSRC hRsrc )
|
||
{
|
||
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
|
||
dprintf_resource(stddeb, "SizeofResource: module="NPFMT" res="NPFMT"\n",
|
||
hModule, hRsrc );
|
||
fprintf(stderr,"SizeofResource32: not implemented\n");
|
||
return 0;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* LoadAccelerators [USER.177]
|
||
*/
|
||
HANDLE32 WIN32_LoadAcceleratorsW(HINSTANCE instance, LPCWSTR lpTableName)
|
||
{
|
||
#if 0
|
||
HANDLE32 hAccel;
|
||
HANDLE32 rsc_mem;
|
||
HANDLE32 hRsrc;
|
||
BYTE *lp;
|
||
ACCELHEADER *lpAccelTbl;
|
||
int i, n;
|
||
|
||
if (HIWORD(lpTableName))
|
||
dprintf_accel( stddeb, "LoadAccelerators: "NPFMT" '%s'\n",
|
||
instance, (char *)( lpTableName ) );
|
||
else
|
||
dprintf_accel( stddeb, "LoadAccelerators: "NPFMT" %04x\n",
|
||
instance, LOWORD(lpTableName) );
|
||
|
||
if (!(hRsrc = FindResource32( instance, lpTableName,
|
||
(LPCWSTR)RT_ACCELERATOR )))
|
||
return 0;
|
||
if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0;
|
||
|
||
lp = (BYTE *)LockResource32(rsc_mem);
|
||
n = SizeofResource( instance, hRsrc ) / sizeof(ACCELENTRY);
|
||
hAccel = GlobalAlloc(GMEM_MOVEABLE,
|
||
sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
|
||
lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
|
||
lpAccelTbl->wCount = 0;
|
||
for (i = 0; i < n; i++) {
|
||
lpAccelTbl->tbl[i].type = *(lp++);
|
||
lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
|
||
lp += 2;
|
||
lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
|
||
lp += 2;
|
||
if (lpAccelTbl->tbl[i].wEvent == 0) break;
|
||
dprintf_accel(stddeb,
|
||
"Accelerator #%u / event=%04X id=%04X type=%02X \n",
|
||
i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
|
||
lpAccelTbl->tbl[i].type);
|
||
lpAccelTbl->wCount++;
|
||
}
|
||
GlobalUnlock(hAccel);
|
||
FreeResource( rsc_mem );
|
||
return hAccel;
|
||
#else
|
||
fprintf(stderr,"LoadAcceleratorsW: not implemented\n");
|
||
return 0;
|
||
#endif
|
||
}
|
||
|
||
HANDLE32 WIN32_LoadAcceleratorsA(HINSTANCE instance, LPCSTR lpTableName)
|
||
{
|
||
LPWSTR uni=STRING32_DupAnsiToUni(lpTableName);
|
||
HANDLE32 result=WIN32_LoadAcceleratorsW(instance,uni);
|
||
free(uni);
|
||
return result;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* LoadString
|
||
*/
|
||
int
|
||
WIN32_LoadStringW(HINSTANCE instance, DWORD resource_id, LPWSTR buffer, int buflen)
|
||
{
|
||
HANDLE32 hmem, hrsrc;
|
||
WCHAR *p;
|
||
int string_num;
|
||
int i;
|
||
|
||
dprintf_resource(stddeb, "LoadString: instance = "NPFMT", id = %04x, buffer = %08x, "
|
||
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
|
||
|
||
hrsrc = FindResource32( instance, (LPCWSTR)((resource_id>>4)+1),
|
||
(LPCWSTR)RT_STRING );
|
||
if (!hrsrc) return 0;
|
||
hmem = LoadResource32( instance, hrsrc );
|
||
if (!hmem) return 0;
|
||
|
||
p = LockResource32(hmem);
|
||
string_num = resource_id & 0x000f;
|
||
for (i = 0; i < string_num; i++)
|
||
p += *p + 1;
|
||
|
||
dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
|
||
|
||
i = MIN(buflen - 1, *p);
|
||
if (buffer == NULL)
|
||
return i;
|
||
if (i > 0) {
|
||
memcpy(buffer, p + 1, i * sizeof (WCHAR));
|
||
buffer[i] = (WCHAR) 0;
|
||
} else {
|
||
if (buflen > 1) {
|
||
buffer[0] = (WCHAR) 0;
|
||
return 0;
|
||
}
|
||
#if 0
|
||
fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
|
||
fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
|
||
#endif
|
||
}
|
||
dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
|
||
return i;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* LoadStringA
|
||
*/
|
||
int
|
||
WIN32_LoadStringA(HINSTANCE instance, DWORD resource_id, LPSTR buffer, int buflen)
|
||
{
|
||
WCHAR *buffer2 = xmalloc(buflen*2);
|
||
int retval = WIN32_LoadStringW(instance, resource_id, buffer2, buflen);
|
||
|
||
while (*buffer2)
|
||
*buffer++ = (char) *buffer2++;
|
||
*buffer = 0;
|
||
return retval;
|
||
}
|
||
|
||
HICON LoadIconW32(HINSTANCE hisnt, LPCTSTR lpszIcon)
|
||
|
||
{
|
||
return LoadIcon(0, IDI_APPLICATION);
|
||
}
|
||
|
||
HICON LoadIconA32(HINSTANCE hinst, LPCTSTR lpszIcon)
|
||
|
||
{
|
||
return LoadIconW32(hinst, lpszIcon);
|
||
}
|
||
/**********************************************************************
|
||
* LoadBitmapW
|
||
*/
|
||
HBITMAP WIN32_LoadBitmapW( HANDLE instance, LPCWSTR name )
|
||
{
|
||
HBITMAP hbitmap = 0;
|
||
HDC hdc;
|
||
HANDLE32 hRsrc;
|
||
HANDLE32 handle;
|
||
BITMAPINFO *info;
|
||
|
||
if (!instance) /* OEM bitmap */
|
||
{
|
||
if (HIWORD((int)name)) return 0;
|
||
return OBM_LoadBitmap( LOWORD((int)name) );
|
||
}
|
||
|
||
if (!(hRsrc = FindResource32( instance, name,
|
||
(LPWSTR)RT_BITMAP ))) return 0;
|
||
if (!(handle = LoadResource32( instance, hRsrc ))) return 0;
|
||
|
||
info = (BITMAPINFO *)LockResource32( handle );
|
||
if ((hdc = GetDC(0)) != 0)
|
||
{
|
||
char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
|
||
hbitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
|
||
bits, info, DIB_RGB_COLORS );
|
||
ReleaseDC( 0, hdc );
|
||
}
|
||
return hbitmap;
|
||
}
|
||
/**********************************************************************
|
||
* LoadBitmapA
|
||
*/
|
||
HBITMAP WIN32_LoadBitmapA( HANDLE instance, LPCSTR name )
|
||
{
|
||
HBITMAP res;
|
||
if(!HIWORD(name))
|
||
res = WIN32_LoadBitmapW(instance,(LPWSTR)name);
|
||
else{
|
||
LPWSTR uni=STRING32_DupAnsiToUni(name);
|
||
res=WIN32_LoadBitmapW(instance,uni);
|
||
free(uni);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* WIN32_ParseMenu
|
||
* LoadMenu helper function
|
||
*/
|
||
BYTE* WIN32_ParseMenu(HMENU hMenu,BYTE *it)
|
||
{
|
||
char entry[200]; /* buffer for ANSI names */
|
||
int bufsize=100;
|
||
int len;
|
||
WORD flags;
|
||
WORD wMenuID;
|
||
WCHAR *utext;
|
||
do{
|
||
flags=*(WORD*)it;
|
||
it+=sizeof(WORD);
|
||
/* POPUP entries have no ID, but a sub menu */
|
||
if(flags & MF_POPUP)
|
||
{
|
||
wMenuID = CreatePopupMenu();
|
||
len = STRING32_lstrlenW((LPWSTR)it);
|
||
utext = (WCHAR*)it;
|
||
it += sizeof(WCHAR)*(len+1);
|
||
it = WIN32_ParseMenu(wMenuID,it);
|
||
} else {
|
||
wMenuID=*(WORD*)it;
|
||
it+=sizeof(WORD);
|
||
utext = (LPWSTR)it;
|
||
len = STRING32_lstrlenW((LPWSTR)it);
|
||
it += sizeof(WCHAR)*(len+1);
|
||
if(!wMenuID && !*utext)
|
||
flags |= MF_SEPARATOR;
|
||
}
|
||
if(len>=bufsize) continue; /* hack hack */
|
||
STRING32_UniToAnsi(entry,utext);
|
||
AppendMenu(hMenu,flags,wMenuID,MAKE_SEGPTR(entry));
|
||
}while(!(flags & MF_END));
|
||
return it;
|
||
}
|
||
|
||
/*****************************************************************
|
||
* LoadMenuIndirectW (USER32.371)
|
||
*/
|
||
HMENU WIN32_LoadMenuIndirectW(void *menu)
|
||
{
|
||
BYTE *it=menu;
|
||
HMENU hMenu = CreateMenu();
|
||
/*skip menu header*/
|
||
if(*(DWORD*)it)
|
||
fprintf(stderr,"Unknown menu header\n");
|
||
it+=2*sizeof(WORD);
|
||
WIN32_ParseMenu(hMenu,it);
|
||
return hMenu;
|
||
}
|
||
|
||
/*****************************************************************
|
||
* LoadMenuW (USER32.372)
|
||
*/
|
||
HMENU WIN32_LoadMenuW(HANDLE instance, LPCWSTR name)
|
||
{
|
||
HANDLE32 hrsrc;
|
||
hrsrc=FindResource32(instance,name,(LPWSTR)RT_MENU);
|
||
if(!hrsrc)return 0;
|
||
return WIN32_LoadMenuIndirectW(LoadResource32(instance, hrsrc));
|
||
}
|
||
|
||
/*****************************************************************
|
||
* LoadMenuIndirectA (USER32.370)
|
||
*/
|
||
HMENU WIN32_LoadMenuIndirectA(void *menu)
|
||
{
|
||
fprintf(stderr,"WIN32_LoadMenuIndirectA not implemented\n");
|
||
return 0;
|
||
}
|
||
|
||
/*****************************************************************
|
||
* LoadMenuA (USER32.370)
|
||
*/
|
||
HMENU WIN32_LoadMenuA(HANDLE instance,LPCSTR name)
|
||
{
|
||
HMENU res;
|
||
if(!HIWORD(name))
|
||
res = WIN32_LoadMenuW(instance,(LPWSTR)name);
|
||
else{
|
||
LPWSTR uni=STRING32_DupAnsiToUni(name);
|
||
res=WIN32_LoadMenuW(instance,uni);
|
||
free(uni);
|
||
}
|
||
return res;
|
||
}
|