mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 14:30:57 +00:00
bugfixes for menus
svn path=/trunk/; revision=5759
This commit is contained in:
parent
ef6eb3eb50
commit
e570fadda7
3 changed files with 150 additions and 65 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.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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
@ -486,7 +501,7 @@ IntInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
|
|||
PMENU_ITEM CurItem;
|
||||
PMENU_ITEM LastItem = NULL;
|
||||
UINT npos = 0;
|
||||
|
||||
|
||||
CurItem = MenuObject->MenuItemList;
|
||||
if(pos <= -1)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -539,7 +554,7 @@ IntInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
|
|||
}
|
||||
}
|
||||
MenuObject->MenuItemCount++;
|
||||
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
|
@ -603,7 +618,7 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPCMENUITEMINFO
|
|||
MenuItem->dwTypeData = 0;
|
||||
MenuItem->cch = 0;
|
||||
}*/
|
||||
|
||||
|
||||
MenuItem->fType = lpmii->fType;
|
||||
MenuItem->cch = lpmii->cch;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -704,7 +732,7 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, WINBOOL fByPosition,
|
|||
MenuItem->dwItemData = (ULONG_PTR)NULL;
|
||||
MenuItem->cch = 0;
|
||||
MenuItem->hbmpItem = (HBITMAP)0;
|
||||
|
||||
|
||||
if(!IntSetMenuItemInfo(MenuObject, MenuItem, lpmii))
|
||||
{
|
||||
ExFreePool(MenuItem);
|
||||
|
|
Loading…
Reference in a new issue