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 * 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.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 * PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/menu.c * FILE: lib/user32/windows/menu.c
@ -192,14 +192,16 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
* *
* NOTE: flags is equivalent to the mtOption field * 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; WORD flags, id = 0;
HMENU hSubMenu;
LPCSTR str; LPCSTR str;
BOOL end = FALSE; BOOL end = FALSE;
do do
{ {
hSubMenu = (HMENU)0;
flags = GET_WORD(res); flags = GET_WORD(res);
/* remove MF_END flag before passing it to AppendMenu()! */ /* remove MF_END flag before passing it to AppendMenu()! */
@ -219,15 +221,23 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR); res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
if (flags & MF_POPUP) if (flags & MF_POPUP)
{ {
HMENU hSubMenu = CreatePopupMenu(); if(!TopLevel)
{
hSubMenu = CreatePopupMenu();
if(!hSubMenu) return NULL; if(!hSubMenu) return NULL;
if(!(res = MENU_ParseResource(res, hSubMenu, unicode))) }
else
hSubMenu = hMenu;
if(!(res = MENU_ParseResource(res, hSubMenu, FALSE, unicode)))
return NULL; return NULL;
if(!TopLevel)
{
if(!unicode) if(!unicode)
AppendMenuA(hMenu, flags, (UINT)hSubMenu, str); AppendMenuA(hMenu, flags, (UINT)hSubMenu, str);
else else
AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str); AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str);
} }
}
else /* Not a popup */ else /* Not a popup */
{ {
if(!unicode) if(!unicode)
@ -734,7 +744,7 @@ HiliteMenuItem(
/* /*
* @unimplemented * @implemented
*/ */
WINBOOL WINBOOL
STDCALL STDCALL
@ -745,9 +755,32 @@ InsertMenuA(
UINT_PTR uIDNewItem, UINT_PTR uIDNewItem,
LPCSTR lpNewItem) LPCSTR lpNewItem)
{ {
UNIMPLEMENTED; 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; return FALSE;
} }
}
mii.dwTypeData = (LPSTR)lpNewItem;
return InsertMenuItemA(hMenu, uPosition, (WINBOOL)!(MF_BYPOSITION & uFlags), &mii);
}
/* /*
@ -808,6 +841,7 @@ InsertMenuItemW(
BOOL CleanHeap = FALSE; BOOL CleanHeap = FALSE;
ULONG len = 0; ULONG len = 0;
HANDLE hHeap = RtlGetProcessHeap(); HANDLE hHeap = RtlGetProcessHeap();
mi.hbmpItem = (HBITMAP)0;
// while we could just pass 'lpmii' to win32k, we make a copy so that // 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 // if a bad user passes bad data, we crash his process instead of the
@ -821,6 +855,8 @@ InsertMenuItemW(
/* copy the text string */ /* copy the text string */
if((mi.fMask & (MIIM_TYPE | MIIM_STRING)) && if((mi.fMask & (MIIM_TYPE | MIIM_STRING)) &&
(MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData) (MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData)
{
if(lpmii->cch > 0)
{ {
len = lstrlenW(lpmii->dwTypeData); len = lstrlenW(lpmii->dwTypeData);
mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR)); mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR));
@ -833,6 +869,7 @@ InsertMenuItemW(
CleanHeap = TRUE; CleanHeap = TRUE;
mi.cch = len; mi.cch = len;
} }
};
res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi); res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi);
@ -843,7 +880,7 @@ InsertMenuItemW(
/* /*
* @unimplemented * @implemented
*/ */
WINBOOL WINBOOL
STDCALL STDCALL
@ -854,8 +891,28 @@ InsertMenuW(
UINT_PTR uIDNewItem, UINT_PTR uIDNewItem,
LPCWSTR lpNewItem) LPCWSTR lpNewItem)
{ {
UNIMPLEMENTED; MENUITEMINFOW mii;
return FALSE; 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); offset = GET_WORD(p);
p += sizeof(WORD) + offset; p += sizeof(WORD) + offset;
if (!(hMenu = CreateMenu())) return 0; if (!(hMenu = CreateMenu())) return 0;
if (!MENU_ParseResource(p, hMenu, TRUE)) if (!MENU_ParseResource(p, hMenu, TRUE, TRUE))
{ {
DestroyMenu(hMenu); DestroyMenu(hMenu);
return 0; return 0;

View file

@ -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: 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 * PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/messagebox.c * FILE: lib/user32/windows/messagebox.c
@ -700,7 +700,7 @@ MessageBeep(UINT uType)
switch(uType) switch(uType)
{ {
case 0xFFFFFFFF: case 0xFFFFFFFF:
//if(WaveOutGetNumDevs() == 0) if(waveOutGetNumDevs() == 0)
return Beep(500, 100); // Beep through speaker return Beep(500, 100); // Beep through speaker
/* fall through */ /* fall through */
case MB_OK: case MB_OK:

View file

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