user.exe16: Support Windows 2 menus.

Signed-off-by: Martin Payne <development@martinpayne.me.uk>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Martin Payne 2017-09-24 09:04:51 +01:00 committed by Alexandre Julliard
parent c91a531957
commit 5ec4d1be97
3 changed files with 34 additions and 12 deletions

View File

@ -706,6 +706,7 @@
@ stdcall -arch=win32 GetCurrentTask() @ stdcall -arch=win32 GetCurrentTask()
@ stdcall -arch=win32 GetDOSEnvironment16() @ stdcall -arch=win32 GetDOSEnvironment16()
@ stdcall -arch=win32 GetExePtr(long) @ stdcall -arch=win32 GetExePtr(long)
@ stdcall -arch=win32 GetExeVersion16()
@ stdcall -arch=win32 GetExpWinVer16(long) @ stdcall -arch=win32 GetExpWinVer16(long)
@ stdcall -arch=win32 GetModuleHandle16(str) @ stdcall -arch=win32 GetModuleHandle16(str)
@ stdcall -arch=win32 GlobalReAlloc16(long long long) @ stdcall -arch=win32 GlobalReAlloc16(long long long)

View File

@ -1428,7 +1428,7 @@ HMENU16 WINAPI LookupMenuHandle16( HMENU16 hmenu, INT16 id )
} }
static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu ) static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu, BOOL oldFormat )
{ {
WORD flags, id = 0; WORD flags, id = 0;
LPCSTR str; LPCSTR str;
@ -1436,11 +1436,21 @@ static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu )
do do
{ {
flags = GET_WORD(res); /* Windows 3.00 and later use a WORD for the flags, whereas 1.x and 2.x use a BYTE. */
if (oldFormat)
{
flags = GET_BYTE(res);
res += sizeof(BYTE);
}
else
{
flags = GET_WORD(res);
res += sizeof(WORD);
}
end_flag = flags & MF_END; end_flag = flags & MF_END;
/* Remove MF_END because it has the same value as MF_HILITE */ /* Remove MF_END because it has the same value as MF_HILITE */
flags &= ~MF_END; flags &= ~MF_END;
res += sizeof(WORD);
if (!(flags & MF_POPUP)) if (!(flags & MF_POPUP))
{ {
id = GET_WORD(res); id = GET_WORD(res);
@ -1452,7 +1462,7 @@ static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu )
{ {
HMENU hSubMenu = CreatePopupMenu(); HMENU hSubMenu = CreatePopupMenu();
if (!hSubMenu) return NULL; if (!hSubMenu) return NULL;
if (!(res = parse_menu_resource( res, hSubMenu ))) return NULL; if (!(res = parse_menu_resource( res, hSubMenu, oldFormat ))) return NULL;
AppendMenuA( hMenu, flags, (UINT_PTR)hSubMenu, str ); AppendMenuA( hMenu, flags, (UINT_PTR)hSubMenu, str );
} }
else /* Not a popup */ else /* Not a popup */
@ -1468,22 +1478,32 @@ static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu )
*/ */
HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template ) HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template )
{ {
BOOL oldFormat;
HMENU hMenu; HMENU hMenu;
WORD version, offset; WORD version, offset;
LPCSTR p = template; LPCSTR p = template;
TRACE("(%p)\n", template ); TRACE("(%p)\n", template );
version = GET_WORD(p);
p += sizeof(WORD); /* Windows 1.x and 2.x menus have a slightly different menu format from 3.x menus */
if (version) oldFormat = (GetExeVersion16() < 0x0300);
/* Windows 3.00 and later menu items are preceded by a MENUITEMTEMPLATEHEADER structure */
if (!oldFormat)
{ {
WARN("version must be 0 for Win16\n" ); version = GET_WORD(p);
return 0; p += sizeof(WORD);
if (version)
{
WARN("version must be 0 for Win16 >= 3.00 applications\n" );
return 0;
}
offset = GET_WORD(p);
p += sizeof(WORD) + offset;
} }
offset = GET_WORD(p);
p += sizeof(WORD) + offset;
if (!(hMenu = CreateMenu())) return 0; if (!(hMenu = CreateMenu())) return 0;
if (!parse_menu_resource( p, hMenu )) if (!parse_menu_resource( p, hMenu, oldFormat ))
{ {
DestroyMenu( hMenu ); DestroyMenu( hMenu );
return 0; return 0;

View File

@ -95,6 +95,7 @@ extern LRESULT WINPROC_CallProc32ATo16( winproc_callback16_t callback, HWND hwnd
extern void call_WH_CALLWNDPROC_hook( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp ) DECLSPEC_HIDDEN; extern void call_WH_CALLWNDPROC_hook( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp ) DECLSPEC_HIDDEN;
#define GET_BYTE(ptr) (*(const BYTE *)(ptr))
#define GET_WORD(ptr) (*(const WORD *)(ptr)) #define GET_WORD(ptr) (*(const WORD *)(ptr))
#define GET_DWORD(ptr) (*(const DWORD *)(ptr)) #define GET_DWORD(ptr) (*(const DWORD *)(ptr))