mirror of
https://github.com/reactos/reactos.git
synced 2024-11-07 15:10:53 +00:00
Implemented LoadMenuIndirectW()
svn path=/trunk/; revision=5355
This commit is contained in:
parent
08210803d8
commit
66615a0c8a
1 changed files with 187 additions and 4 deletions
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: menu.c,v 1.12 2003/07/31 23:06:43 weiden Exp $
|
||||
/* $Id: menu.c,v 1.13 2003/08/01 00:44:27 weiden Exp $
|
||||
*
|
||||
* PROJECT: ReactOS user32.dll
|
||||
* FILE: lib/user32/windows/menu.c
|
||||
|
@ -94,6 +94,158 @@ HANDLE hMenuDefSysPopup = 0;
|
|||
|
||||
#define NO_SELECTED_ITEM (0xffff)
|
||||
|
||||
#ifndef MF_END
|
||||
#define MF_END 0x0080
|
||||
#endif
|
||||
|
||||
|
||||
/* INTERNAL FUNCTIONS ********************************************************/
|
||||
|
||||
/* Rip the fun and easy to use and fun WINE unicode string manipulation routines.
|
||||
* Of course I didnt copy the ASM code because we want this to be portable
|
||||
* and it needs to go away.
|
||||
*/
|
||||
|
||||
static inline unsigned int strlenW( const WCHAR *str )
|
||||
{
|
||||
const WCHAR *s = str;
|
||||
while (*s) s++;
|
||||
return s - str;
|
||||
}
|
||||
|
||||
static inline WCHAR *strncpyW( WCHAR *str1, const WCHAR *str2, int n )
|
||||
{
|
||||
WCHAR *ret = str1;
|
||||
while (n-- > 0) if (!(*str1++ = *str2++)) break;
|
||||
while (n-- > 0) *str1++ = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline WCHAR *strcpyW( WCHAR *dst, const WCHAR *src )
|
||||
{
|
||||
WCHAR *p = dst;
|
||||
while ((*p++ = *src++));
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline WCHAR *strcatW( WCHAR *dst, const WCHAR *src )
|
||||
{
|
||||
strcpyW( dst + strlenW(dst), src );
|
||||
return dst;
|
||||
}
|
||||
|
||||
#ifndef GET_WORD
|
||||
#define GET_WORD(ptr) (*(WORD *)(ptr))
|
||||
#endif
|
||||
#ifndef GET_DWORD
|
||||
#define GET_DWORD(ptr) (*(DWORD *)(ptr))
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* MENUEX_ParseResource
|
||||
*
|
||||
* Parse an extended menu resource and add items to the menu.
|
||||
* Return a pointer to the end of the resource.
|
||||
*/
|
||||
static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
|
||||
{
|
||||
WORD resinfo;
|
||||
|
||||
do {
|
||||
MENUITEMINFO mii;
|
||||
|
||||
mii.cbSize = sizeof(mii);
|
||||
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE;
|
||||
mii.fType = GET_DWORD(res);
|
||||
res += sizeof(DWORD);
|
||||
mii.fState = GET_DWORD(res);
|
||||
res += sizeof(DWORD);
|
||||
mii.wID = GET_DWORD(res);
|
||||
res += sizeof(DWORD);
|
||||
resinfo = GET_WORD(res);
|
||||
res += sizeof(WORD);
|
||||
/* Align the text on a word boundary. */
|
||||
res += (~((int)res - 1)) & 1;
|
||||
mii.dwTypeData = (LPWSTR) res;
|
||||
res += (1 + strlenW(mii.dwTypeData)) * sizeof(WCHAR);
|
||||
/* Align the following fields on a dword boundary. */
|
||||
res += (~((int)res - 1)) & 3;
|
||||
|
||||
if (resinfo & 1) { /* Pop-up? */
|
||||
/* DWORD helpid = GET_DWORD(res); FIXME: use this. */
|
||||
res += sizeof(DWORD);
|
||||
mii.hSubMenu = CreatePopupMenu();
|
||||
if (!mii.hSubMenu)
|
||||
return NULL;
|
||||
if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) {
|
||||
DestroyMenu(mii.hSubMenu);
|
||||
return NULL;
|
||||
}
|
||||
mii.fMask |= MIIM_SUBMENU;
|
||||
mii.fType |= MF_POPUP;
|
||||
}
|
||||
else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR))
|
||||
{
|
||||
DbgPrint("WARN: Converting NULL menu item %04x, type %04x to SEPARATOR\n",
|
||||
mii.wID, mii.fType);
|
||||
mii.fType |= MF_SEPARATOR;
|
||||
}
|
||||
InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
|
||||
} while (!(resinfo & MF_END));
|
||||
return res;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* MENU_ParseResource
|
||||
*
|
||||
* Parse a standard menu resource and add items to the menu.
|
||||
* Return a pointer to the end of the resource.
|
||||
*
|
||||
* NOTE: flags is equivalent to the mtOption field
|
||||
*/
|
||||
static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
|
||||
{
|
||||
WORD flags, id = 0;
|
||||
LPCSTR str;
|
||||
BOOL end = FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
flags = GET_WORD(res);
|
||||
|
||||
/* remove MF_END flag before passing it to AppendMenu()! */
|
||||
end = (flags & MF_END);
|
||||
if(end) flags ^= MF_END;
|
||||
|
||||
res += sizeof(WORD);
|
||||
if (!(flags & MF_POPUP))
|
||||
{
|
||||
id = GET_WORD(res);
|
||||
res += sizeof(WORD);
|
||||
}
|
||||
str = res;
|
||||
if (!unicode) res += strlen(str) + 1;
|
||||
else res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
|
||||
if (flags & MF_POPUP)
|
||||
{
|
||||
HMENU hSubMenu = CreatePopupMenu();
|
||||
if (!hSubMenu) return NULL;
|
||||
if (!(res = MENU_ParseResource( res, hSubMenu, unicode )))
|
||||
return NULL;
|
||||
if (!unicode) AppendMenuA( hMenu, flags, (UINT)hSubMenu, str );
|
||||
else AppendMenuW( hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str );
|
||||
}
|
||||
else /* Not a popup */
|
||||
{
|
||||
if (!unicode) AppendMenuA( hMenu, flags, id, *str ? str : NULL );
|
||||
else AppendMenuW( hMenu, flags, id,
|
||||
*(LPCWSTR)str ? (LPCWSTR)str : NULL );
|
||||
}
|
||||
} while (!end);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static BOOL
|
||||
|
@ -831,13 +983,44 @@ LoadMenuIndirectA(CONST MENUTEMPLATE *lpMenuTemplate)
|
|||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
HMENU STDCALL
|
||||
LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return (HMENU)0;
|
||||
HMENU hMenu;
|
||||
WORD version, offset;
|
||||
LPCSTR p = (LPCSTR)lpMenuTemplate;
|
||||
|
||||
version = GET_WORD(p);
|
||||
p += sizeof(WORD);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0: /* standard format is version of 0 */
|
||||
offset = GET_WORD(p);
|
||||
p += sizeof(WORD) + offset;
|
||||
if (!(hMenu = CreateMenu())) return 0;
|
||||
if (!MENU_ParseResource( p, hMenu, TRUE ))
|
||||
{
|
||||
DestroyMenu( hMenu );
|
||||
return 0;
|
||||
}
|
||||
return hMenu;
|
||||
case 1: /* extended format is version of 1 */
|
||||
offset = GET_WORD(p);
|
||||
p += sizeof(WORD) + offset;
|
||||
if (!(hMenu = CreateMenu())) return 0;
|
||||
if (!MENUEX_ParseResource( p, hMenu))
|
||||
{
|
||||
DestroyMenu( hMenu );
|
||||
return 0;
|
||||
}
|
||||
return hMenu;
|
||||
default:
|
||||
DbgPrint("LoadMenuIndirectW(): version %d not supported.\n", version);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue