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
@ -177,8 +177,8 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
mii.wID, mii.fType); mii.wID, mii.fType);
mii.fType |= MF_SEPARATOR; mii.fType |= MF_SEPARATOR;
} }
InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii); InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
} }
while (!(resinfo & MF_END)); while (!(resinfo & MF_END));
return res; return res;
} }
@ -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,14 +221,22 @@ 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)
if(!hSubMenu) return NULL; {
if(!(res = MENU_ParseResource(res, hSubMenu, unicode))) hSubMenu = CreatePopupMenu();
return NULL; if(!hSubMenu) return NULL;
if(!unicode) }
AppendMenuA(hMenu, flags, (UINT)hSubMenu, str);
else 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 */ else /* Not a popup */
{ {
@ -734,7 +744,7 @@ HiliteMenuItem(
/* /*
* @unimplemented * @implemented
*/ */
WINBOOL WINBOOL
STDCALL STDCALL
@ -745,8 +755,31 @@ InsertMenuA(
UINT_PTR uIDNewItem, UINT_PTR uIDNewItem,
LPCSTR lpNewItem) LPCSTR lpNewItem)
{ {
UNIMPLEMENTED; MENUITEMINFOA mii;
return FALSE; 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; 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
@ -822,17 +856,20 @@ InsertMenuItemW(
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)
{ {
len = lstrlenW(lpmii->dwTypeData); if(lpmii->cch > 0)
mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR));
if(!mi.dwTypeData)
{ {
SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY)); len = lstrlenW(lpmii->dwTypeData);
return FALSE; 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); 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,7 +76,8 @@
{ \ { \
if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \ if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
(MenuItem)->dwTypeData) { \ (MenuItem)->dwTypeData) { \
ExFreePool((MenuItem)->dwTypeData); \ if((MenuItem)->cch) \
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)
{ {
DbgPrint("Copy menu item %ws\n", (LPWSTR)MenuItem->dwTypeData); if(MenuItem->cch && NewMenuItem->dwTypeData)
NewMenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (MenuItem->cch + 1) * sizeof(WCHAR));
if(!NewMenuItem->dwTypeData)
{ {
ExFreePool(NewMenuItem); NewMenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (MenuItem->cch + 1) * sizeof(WCHAR));
goto finish; 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->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;
@ -486,7 +501,7 @@ IntInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
PMENU_ITEM CurItem; PMENU_ITEM CurItem;
PMENU_ITEM LastItem = NULL; PMENU_ITEM LastItem = NULL;
UINT npos = 0; UINT npos = 0;
CurItem = MenuObject->MenuItemList; CurItem = MenuObject->MenuItemList;
if(pos <= -1) if(pos <= -1)
{ {
@ -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;
} }
@ -539,7 +554,7 @@ IntInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
} }
} }
MenuObject->MenuItemCount++; MenuObject->MenuItemCount++;
return npos; return npos;
} }
@ -603,7 +618,7 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPCMENUITEMINFO
MenuItem->dwTypeData = 0; MenuItem->dwTypeData = 0;
MenuItem->cch = 0; MenuItem->cch = 0;
}*/ }*/
MenuItem->fType = lpmii->fType; MenuItem->fType = lpmii->fType;
MenuItem->cch = lpmii->cch; MenuItem->cch = lpmii->cch;
@ -643,19 +658,32 @@ 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))
{ {
FreeMenuText(MenuItem); if(lpmii->dwTypeData && lpmii->cch)
MenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (lpmii->cch + 1) * sizeof(WCHAR));
if(!MenuItem->dwTypeData)
{ {
MenuItem->cch = 0; FreeMenuText(MenuItem);
/* FIXME Set last error code? */ MenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (lpmii->cch + 1) * sizeof(WCHAR));
SetLastWin32Error(STATUS_NO_MEMORY); if(!MenuItem->dwTypeData)
return FALSE; {
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; else
memcpy(MenuItem->dwTypeData, lpmii->dwTypeData, (lpmii->cch + 1) * sizeof(WCHAR)); {
MenuItem->fType = MF_SEPARATOR;
MenuItem->dwTypeData = NULL;
MenuItem->cch = 0;
}
}
else
{
MenuItem->dwTypeData = NULL;
} }
return TRUE; return TRUE;
@ -704,7 +732,7 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, WINBOOL fByPosition,
MenuItem->dwItemData = (ULONG_PTR)NULL; MenuItem->dwItemData = (ULONG_PTR)NULL;
MenuItem->cch = 0; MenuItem->cch = 0;
MenuItem->hbmpItem = (HBITMAP)0; MenuItem->hbmpItem = (HBITMAP)0;
if(!IntSetMenuItemInfo(MenuObject, MenuItem, lpmii)) if(!IntSetMenuItemInfo(MenuObject, MenuItem, lpmii))
{ {
ExFreePool(MenuItem); ExFreePool(MenuItem);