bugfixes for menus

svn path=/trunk/; revision=5759
This commit is contained in:
Thomas Bluemel 2003-08-22 16:01:01 +00:00
parent ef6eb3eb50
commit e570fadda7
3 changed files with 150 additions and 65 deletions

View file

@ -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.27 2003/08/21 20:29:43 weiden Exp $
/* $Id: menu.c,v 1.28 2003/08/22 16:01:01 weiden Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/menu.c
@ -177,8 +177,8 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
mii.wID, mii.fType);
mii.fType |= MF_SEPARATOR;
}
InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
}
InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
}
while (!(resinfo & MF_END));
return res;
}
@ -192,14 +192,16 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
*
* NOTE: flags is equivalent to the mtOption field
*/
static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL TopLevel, BOOL unicode )
{
WORD flags, id = 0;
HMENU hSubMenu;
LPCSTR str;
BOOL end = FALSE;
do
{
hSubMenu = (HMENU)0;
flags = GET_WORD(res);
/* remove MF_END flag before passing it to AppendMenu()! */
@ -219,14 +221,22 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
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);
if(!TopLevel)
{
hSubMenu = CreatePopupMenu();
if(!hSubMenu) return NULL;
}
else
AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str);
hSubMenu = hMenu;
if(!(res = MENU_ParseResource(res, hSubMenu, FALSE, unicode)))
return NULL;
if(!TopLevel)
{
if(!unicode)
AppendMenuA(hMenu, flags, (UINT)hSubMenu, str);
else
AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str);
}
}
else /* Not a popup */
{
@ -734,7 +744,7 @@ HiliteMenuItem(
/*
* @unimplemented
* @implemented
*/
WINBOOL
STDCALL
@ -745,8 +755,31 @@ InsertMenuA(
UINT_PTR uIDNewItem,
LPCSTR lpNewItem)
{
UNIMPLEMENTED;
return FALSE;
MENUITEMINFOA mii;
mii.cbSize = sizeof(MENUITEMINFOA);
mii.fMask = MIIM_FTYPE | MIIM_STRING;
mii.fType = 0;
if(uFlags & MF_BITMAP)
mii.fType |= MFT_BITMAP;
else
{
if(uFlags & MF_STRING)
{
mii.fType |= MFT_STRING;
}
else if(uFlags & MF_OWNERDRAW)
{
mii.fType |= MFT_OWNERDRAW;
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
mii.dwTypeData = (LPSTR)lpNewItem;
return InsertMenuItemA(hMenu, uPosition, (WINBOOL)!(MF_BYPOSITION & uFlags), &mii);
}
@ -808,6 +841,7 @@ InsertMenuItemW(
BOOL CleanHeap = FALSE;
ULONG len = 0;
HANDLE hHeap = RtlGetProcessHeap();
mi.hbmpItem = (HBITMAP)0;
// while we could just pass 'lpmii' to win32k, we make a copy so that
// if a bad user passes bad data, we crash his process instead of the
@ -822,17 +856,20 @@ InsertMenuItemW(
if((mi.fMask & (MIIM_TYPE | MIIM_STRING)) &&
(MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData)
{
len = lstrlenW(lpmii->dwTypeData);
mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR));
if(!mi.dwTypeData)
if(lpmii->cch > 0)
{
SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
return FALSE;
len = lstrlenW(lpmii->dwTypeData);
mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR));
if(!mi.dwTypeData)
{
SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
return FALSE;
}
memcpy(&mi.dwTypeData, &lpmii->dwTypeData, len);
CleanHeap = TRUE;
mi.cch = len;
}
memcpy(&mi.dwTypeData, &lpmii->dwTypeData, len);
CleanHeap = TRUE;
mi.cch = len;
}
};
res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi);
@ -843,7 +880,7 @@ InsertMenuItemW(
/*
* @unimplemented
* @implemented
*/
WINBOOL
STDCALL
@ -854,8 +891,28 @@ InsertMenuW(
UINT_PTR uIDNewItem,
LPCWSTR lpNewItem)
{
UNIMPLEMENTED;
return FALSE;
MENUITEMINFOW mii;
mii.cbSize = sizeof(MENUITEMINFOW);
mii.fMask = MIIM_FTYPE | MIIM_STRING;
mii.fType = 0;
if(uFlags & MF_BITMAP)
{
mii.fType |= MFT_BITMAP;
}
else if(uFlags & MF_OWNERDRAW)
{
mii.fType |= MFT_OWNERDRAW;
}
else if(uFlags & MF_POPUP)
{
mii.fMask |= MIIM_SUBMENU;
mii.hSubMenu = (HMENU)uIDNewItem;
mii.wID = 0;
}
mii.dwTypeData = (LPWSTR)lpNewItem;
return InsertMenuItemW(hMenu, uPosition, (WINBOOL)!(MF_BYPOSITION & uFlags), &mii);
}
@ -919,7 +976,7 @@ LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate)
offset = GET_WORD(p);
p += sizeof(WORD) + offset;
if (!(hMenu = CreateMenu())) return 0;
if (!MENU_ParseResource(p, hMenu, TRUE))
if (!MENU_ParseResource(p, hMenu, TRUE, TRUE))
{
DestroyMenu(hMenu);
return 0;

View file

@ -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: messagebox.c,v 1.14 2003/08/22 00:39:15 weiden Exp $
/* $Id: messagebox.c,v 1.15 2003/08/22 16:01:01 weiden Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/messagebox.c
@ -700,7 +700,7 @@ MessageBeep(UINT uType)
switch(uType)
{
case 0xFFFFFFFF:
//if(WaveOutGetNumDevs() == 0)
if(waveOutGetNumDevs() == 0)
return Beep(500, 100); // Beep through speaker
/* fall through */
case MB_OK:

View file

@ -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.26 2003/08/22 13:27:09 royce Exp $
/* $Id: menu.c,v 1.27 2003/08/22 16:01:01 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -76,7 +76,8 @@
{ \
if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
(MenuItem)->dwTypeData) { \
ExFreePool((MenuItem)->dwTypeData); \
if((MenuItem)->cch) \
ExFreePool((MenuItem)->dwTypeData); \
(MenuItem)->dwTypeData = 0; \
(MenuItem)->cch = 0; \
} \
@ -94,7 +95,7 @@ CleanupMenuImpl(VOID)
return(STATUS_SUCCESS);
}
#if 0
#if 1
void FASTCALL
DumpMenuItemList(PMENU_ITEM MenuItem)
{
@ -251,9 +252,10 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProc
PMENU_OBJECT FASTCALL
IntCreateMenu(PHANDLE Handle)
{
PMENU_OBJECT MenuObject;
PW32PROCESS Win32Process = PsGetWin32Process();
PMENU_OBJECT MenuObject = (PMENU_OBJECT)ObmCreateObject(
MenuObject = (PMENU_OBJECT)ObmCreateObject(
Win32Process->WindowStation->HandleTable, Handle,
otMenu, sizeof(MENU_OBJECT));
@ -288,7 +290,8 @@ IntCreateMenu(PHANDLE Handle)
BOOL FASTCALL
IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
{
PMENU_ITEM MenuItem, NewMenuItem, Old = NULL;
PMENU_ITEM MenuItem, NewMenuItem = NULL;
PMENU_ITEM Old = NULL;
if(!Source->MenuItemCount)
return FALSE;
@ -300,12 +303,11 @@ IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
while(MenuItem)
{
Old = NewMenuItem;
if(NewMenuItem)
NewMenuItem->Next = MenuItem;
NewMenuItem = ExAllocatePool(PagedPool, sizeof(MENU_ITEM));
if(!NewMenuItem)
{
goto finish;
}
break;
NewMenuItem->fType = MenuItem->fType;
NewMenuItem->fState = MenuItem->fState;
NewMenuItem->wID = MenuItem->wID;
@ -314,28 +316,41 @@ IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
NewMenuItem->hbmpUnchecked = MenuItem->hbmpUnchecked;
NewMenuItem->dwItemData = MenuItem->dwItemData;
NewMenuItem->dwTypeData = MenuItem->dwTypeData;
if((MENU_ITEM_TYPE(NewMenuItem->fType) == MF_STRING) &&
NewMenuItem->dwTypeData)
if((MENU_ITEM_TYPE(NewMenuItem->fType) == MF_STRING))
{
DbgPrint("Copy menu item %ws\n", (LPWSTR)MenuItem->dwTypeData);
NewMenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (MenuItem->cch + 1) * sizeof(WCHAR));
if(!NewMenuItem->dwTypeData)
if(MenuItem->cch && NewMenuItem->dwTypeData)
{
ExFreePool(NewMenuItem);
goto finish;
NewMenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (MenuItem->cch + 1) * sizeof(WCHAR));
if(!NewMenuItem->dwTypeData)
{
ExFreePool(NewMenuItem);
break;
}
memcpy(NewMenuItem->dwTypeData, MenuItem->dwTypeData, (MenuItem->cch + 1) * sizeof(WCHAR));
}
memcpy(NewMenuItem->dwTypeData, MenuItem->dwTypeData, (MenuItem->cch + 1) * sizeof(WCHAR));
else
{
NewMenuItem->cch = MenuItem->cch;
NewMenuItem->dwTypeData = MenuItem->dwTypeData;
}
}
else
{
NewMenuItem->cch = MenuItem->cch;
NewMenuItem->dwTypeData = MenuItem->dwTypeData;
}
NewMenuItem->cch = MenuItem->cch;
NewMenuItem->hbmpItem = MenuItem->hbmpItem;
Old->Next = NewMenuItem;
NewMenuItem->Next = NULL;
Source->MenuItemCount++;
if(Old)
Old->Next = NewMenuItem;
else
Destination->MenuItemList = NewMenuItem;
Destination->MenuItemCount++;
MenuItem = MenuItem->Next;
}
finish:
ExReleaseFastMutexUnsafe(&Source->MenuItemsLock);
ExReleaseFastMutexUnsafe(&Destination->MenuItemsLock);
return TRUE;
@ -527,7 +542,7 @@ IntInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
{
if(LastItem)
{
/* insert at the end */
/* append item */
LastItem->Next = MenuItem;
MenuItem->Next = NULL;
}
@ -643,19 +658,32 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPCMENUITEMINFO
MenuItem->hSubMenu = lpmii->hSubMenu;
}
if((lpmii->fMask & (MIIM_TYPE | MIIM_STRING)) &&
(MENU_ITEM_TYPE(lpmii->fType) == MF_STRING) && lpmii->dwTypeData)
(MENU_ITEM_TYPE(lpmii->fType) == MF_STRING))
{
FreeMenuText(MenuItem);
MenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (lpmii->cch + 1) * sizeof(WCHAR));
if(!MenuItem->dwTypeData)
if(lpmii->dwTypeData && lpmii->cch)
{
MenuItem->cch = 0;
/* FIXME Set last error code? */
SetLastWin32Error(STATUS_NO_MEMORY);
return FALSE;
FreeMenuText(MenuItem);
MenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (lpmii->cch + 1) * sizeof(WCHAR));
if(!MenuItem->dwTypeData)
{
MenuItem->cch = 0;
/* FIXME Set last error code? */
SetLastWin32Error(STATUS_NO_MEMORY);
return FALSE;
}
MenuItem->cch = lpmii->cch;
memcpy(MenuItem->dwTypeData, lpmii->dwTypeData, (lpmii->cch + 1) * sizeof(WCHAR));
}
MenuItem->cch = lpmii->cch;
memcpy(MenuItem->dwTypeData, lpmii->dwTypeData, (lpmii->cch + 1) * sizeof(WCHAR));
else
{
MenuItem->fType = MF_SEPARATOR;
MenuItem->dwTypeData = NULL;
MenuItem->cch = 0;
}
}
else
{
MenuItem->dwTypeData = NULL;
}
return TRUE;