Author: jimtabor
Date: Fri May 30 12:38:04 2014
New Revision: 63502
URL:
http://svn.reactos.org/svn/reactos?rev=63502&view=rev
Log:
[Win32k]
- Fix removing menus and submenus. Dedicated to David Quintana and the New Explorer and
Shell team.
Modified:
trunk/reactos/win32ss/include/ntuser.h
trunk/reactos/win32ss/user/ntuser/menu.c
Modified: trunk/reactos/win32ss/include/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/include/ntuser.h?r…
==============================================================================
--- trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] Fri May 30 12:38:04 2014
@@ -305,6 +305,9 @@
/* Menu Item fType. */
#define MFT_RTOL 0x6000
+
+/* Menu Item fState. */
+#define MFS_HBMMENUBMP 0x20000000
typedef struct tagITEM
{
Modified: trunk/reactos/win32ss/user/ntuser/menu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/menu.c…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/menu.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/menu.c [iso-8859-1] Fri May 30 12:38:04 2014
@@ -178,15 +178,7 @@
BOOL IntDestroyMenu( PMENU pMenu, BOOL bRecurse, BOOL RemoveFromProcess)
{
- /* DestroyMenu should not destroy system menu popup owner */
- if ((pMenu->fFlags & (MNF_POPUP | MNF_SYSSUBMENU)) == MNF_POPUP &&
pMenu->hWnd)
- {
- //PWND pWnd = ValidateHwndNoErr(pMenu->hWnd);
- ERR("FIXME Pop up menu window thing'ie\n");
-
- //co_UserDestroyWindow( pWnd );
- //pMenu->hWnd = 0;
- }
+ PMENU SubMenu;
if (pMenu->rgItems) /* recursively destroy submenus */
{
@@ -194,33 +186,46 @@
ITEM *item = pMenu->rgItems;
for (i = pMenu->cItems; i > 0; i--, item++)
{
- pMenu->cItems--; //// I hate recursion logic! (jt) 4/2014. See r63028
comment for IntDeleteMenuItems.
+ SubMenu = item->spSubMenu;
+ item->spSubMenu = NULL;
+
+ /* Remove Item Text */
FreeMenuText(pMenu,item);
- if (bRecurse && item->spSubMenu)//VerifyMenu(item->spSubMenu))
+
+ /* Remove Item Bitmap and set it for this process */
+ if (item->hbmp && !(item->fState & MFS_HBMMENUBMP))
{
- IntDestroyMenu(item->spSubMenu, bRecurse, RemoveFromProcess);
- item->spSubMenu = NULL;
+ GreSetObjectOwner(item->hbmp, GDI_OBJ_HMGR_POWNED);
+ item->hbmp = NULL;
+ }
+
+ /* Remove Item submenu */
+ if (bRecurse && SubMenu)//VerifyMenu(SubMenu))
+ {
+ /* Release submenu since it was referenced when inserted */
+ IntReleaseMenuObject(SubMenu);
+ IntDestroyMenuObject(SubMenu, bRecurse, RemoveFromProcess);
}
}
+ /* Free the Item */
DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems );
pMenu->rgItems = NULL;
- pMenu->cItems = 0; //// What ever~!
+ pMenu->cItems = 0;
}
return TRUE;
}
BOOL FASTCALL
-IntDestroyMenuObject(PMENU Menu,
- BOOL bRecurse, BOOL RemoveFromProcess)
+IntDestroyMenuObject(PMENU Menu, BOOL bRecurse, BOOL RemoveFromProcess)
{
if(Menu)
{
PWND Window;
-
+
/* Remove all menu items */
IntDestroyMenu( Menu, bRecurse, RemoveFromProcess);
- if(RemoveFromProcess)
+ if (RemoveFromProcess)
{
RemoveEntryList(&Menu->ListEntry);
}
@@ -234,9 +239,17 @@
if (Window)
{
Window->IDMenu = 0;
+
+ /* DestroyMenu should not destroy system menu popup owner */
+ if ((Menu->fFlags & (MNF_POPUP | MNF_SYSSUBMENU)) == MNF_POPUP)
+ {
+ // Should we check it to see if it has Class?
+ ERR("FIXME Pop up menu window thing'ie\n");
+ //co_UserDestroyWindow( Window );
+ //Menu->hWnd = 0;
+ }
}
}
- //UserDereferenceObject(Menu);
ret = UserDeleteObject(Menu->head.h, TYPE_MENU);
if (!ret)
{ // Make sure it is really dead or just marked for deletion.
@@ -338,7 +351,7 @@
BOOL FASTCALL
IntRemoveMenuItem( PMENU pMenu, UINT nPos, UINT wFlags, BOOL bRecurse )
{
- PITEM item, NewItems;
+ PITEM item;
TRACE("(menu=%p pos=%04x flags=%04x)\n",pMenu, nPos, wFlags);
if (!(item = MENU_FindItem( &pMenu, &nPos, wFlags ))) return FALSE;
@@ -364,10 +377,7 @@
item++;
nPos++;
}
- NewItems = DesktopHeapAlloc(pMenu->head.rpdesk, pMenu->cItems *
sizeof(ITEM));
- RtlCopyMemory(NewItems, pMenu->rgItems, pMenu->cItems * sizeof(ITEM));
- DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems);
- pMenu->rgItems = NewItems;
+ pMenu->rgItems = DesktopHeapReAlloc(pMenu->head.rpdesk, pMenu->rgItems,
pMenu->cItems * sizeof(ITEM));
}
return TRUE;
}
@@ -819,6 +829,10 @@
if(lpmii->fMask & MIIM_BITMAP)
{
MenuItem->hbmp = lpmii->hbmpItem;
+ if (MenuItem->hbmp <= HBMMENU_POPUP_MINIMIZE && MenuItem->hbmp
>= HBMMENU_CALLBACK)
+ MenuItem->fState |= MFS_HBMMENUBMP;
+ else
+ MenuItem->fState &= ~MFS_HBMMENUBMP;
}
if(lpmii->fMask & MIIM_CHECKMARKS)
{
@@ -858,6 +872,7 @@
ERR("Pop Up Menu Double Trouble!\n");
SubMenuObject = IntCreateMenu(&hMenu, FALSE); // It will be marked.
if (!SubMenuObject) return FALSE;
+ IntReleaseMenuObject(SubMenuObject); // This will be referenced again
after insertion.
circref = TRUE;
}
if ( MENU_depth( SubMenuObject, 0) > MAXMENUDEPTH )