Sat Mar 2 18:19:06 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [controls/scroll.c] Fixed SCROLL_THUMB painting fixes from Alex Korobka to store the current tracking window. * [files/file.c] Fixed two file descriptor leaks in FILE_OpenFile(). * [if1632/relay32.c] [loader/module.c] [loader/pe_image.c] [tools/build.c] Replaced LOADEDFILEINFO structure by OFSTRUCT. * [memory/atom.c] Reload the pointer to the atom table in ATOM_GetTable() and ATOM_AddAtom() in case the LOCAL_Alloc() calls caused the table to move in linear memory. Fri Mar 1 11:57:13 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl> * [include/callback.h] Added support for CallWordBreakProc(). * [controls/edit.c] New caret handling (really efficient / fast). Implemented EM_SETWORDBREAKPROC and EM_GETWORDBREAKPROC. Fixed EM_SETFONT so it now also creates a proper new caret. Wed Feb 28 22:03:34 1996 Daniel Schepler <daniel@frobnitz.wustl.edu> * [controls/desktop.c] [misc/main.c] [windows/event.c] [windows/win.c] Added WM_DELETE protocol to top-level windows. * [controls/scroll.c] Fixed a problem which caused slow scrolling to continue uncontrollably. * [misc/exec.c] Implemented ExitWindows(). * [windows/win.c] Set top-level owned windows to be transient. Wed Feb 28 19:13:22 1996 Ulrich Schmid <uschmid@mail.hh.provi.de> * [programs/progman/*] Added a program manager. Wed Feb 28 18:38:01 1996 Duncan C Thomson <duncan@spd.eee.strath.ac.uk> * [resources/sysres_Eo.c] Added support for Esperanto [Eo] language. Wed Feb 28 00:23:00 1996 Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk> * [if1632/user32.spec] Added EndDialog, GetDlgItem, GetDlgItemInt, SetDlgItemInt, * [win32/init.c] Added task.h to includes. GetModuleHandleA() - return hInstance if called with NULL parameter. Freecell needs this. NOTE this may indicate a problem with differentiation between hModule and hInstance within Wine. * [win32/resource.c] FindResource32() and LoadResource32() - Removed #if 0's around conversion from hInstance to hModule. See remarks above. * [win32/string32.c] WIN32_UniLen() - removed stray semicolon. Tue Feb 27 21:05:18 1996 Jim Peterson <jspeter@birch.ee.vt.edu> * [windows/caret.c] Set blink rate with call to GetProfileInt(). * [rc/winerc.c] In new_style(), made initial flag settings WS_CHILD | WS_VISIBLE instead of 0. This seems to correspond to Borland's defaults, and the flags can be unset by using the (rather obtuse) "| NOT WS_CHILD" or "| NOT WS_VISIBLE" technique in the *.rc file. * [win32/time.c] In GetLocalTime() and GetSystemTime(), used tv_sec field of result returned by gettimeofday() instead of making second call to time(). This eliminates clock jitter if the seconds change between the two calls (rare, but possible). * [include/wintypes.h] Added "#define _far" and "#define _pascal". * [windows/win.c] Added function GetDesktopHwnd(). * [include/xmalloc.h] Removed the '#ifdef HAVE_STDLIB_H' structure, since it seemed to have been removed from 'configure', and was causing redefinition warnings. Tue Feb 27 19:31:11 1996 Albrecht Kleine <kleine@ak.sax.de> * [windows/winpos.c] Added RDW_ALLCHILDREN flag in SetWindowPos (handling SWP_FRAMECHANGED) to force a repaint when setting menu bars with different rows. Sun Feb 25 21:15:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu> * [windows/syscolors.c] [controls/scroll.c] Fixed DrawFocusRect pen and SCROLL_THUMB painting.
461 lines
13 KiB
C
461 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;
|
||
|
||
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
|
||
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;
|
||
|
||
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
|
||
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;
|
||
}
|