mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +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
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS user32.dll
|
||||||
* FILE: lib/user32/windows/menu.c
|
* FILE: lib/user32/windows/menu.c
|
||||||
|
@ -94,6 +94,158 @@ HANDLE hMenuDefSysPopup = 0;
|
||||||
|
|
||||||
#define NO_SELECTED_ITEM (0xffff)
|
#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 *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
|
@ -831,13 +983,44 @@ LoadMenuIndirectA(CONST MENUTEMPLATE *lpMenuTemplate)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
HMENU STDCALL
|
HMENU STDCALL
|
||||||
LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate)
|
LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
HMENU hMenu;
|
||||||
return (HMENU)0;
|
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