From e570fadda72bc0772d915f4166fe4660df67a89b Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Fri, 22 Aug 2003 16:01:01 +0000 Subject: [PATCH] bugfixes for menus svn path=/trunk/; revision=5759 --- reactos/lib/user32/windows/menu.c | 111 ++++++++++++++++++------ reactos/lib/user32/windows/messagebox.c | 4 +- reactos/subsys/win32k/ntuser/menu.c | 100 +++++++++++++-------- 3 files changed, 150 insertions(+), 65 deletions(-) diff --git a/reactos/lib/user32/windows/menu.c b/reactos/lib/user32/windows/menu.c index 282d7e950b7..8227fb5ed32 100644 --- a/reactos/lib/user32/windows/menu.c +++ b/reactos/lib/user32/windows/menu.c @@ -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; diff --git a/reactos/lib/user32/windows/messagebox.c b/reactos/lib/user32/windows/messagebox.c index c97316e836b..46a2eaac2f7 100644 --- a/reactos/lib/user32/windows/messagebox.c +++ b/reactos/lib/user32/windows/messagebox.c @@ -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: diff --git a/reactos/subsys/win32k/ntuser/menu.c b/reactos/subsys/win32k/ntuser/menu.c index 0723c90281f..dce698bc97c 100644 --- a/reactos/subsys/win32k/ntuser/menu.c +++ b/reactos/subsys/win32k/ntuser/menu.c @@ -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);