mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[Win32k]
- Fix removing menus and submenus. Dedicated to David Quintana and the New Explorer and Shell team. svn path=/trunk/; revision=63502
This commit is contained in:
parent
137dc25b64
commit
4dc4711006
2 changed files with 42 additions and 24 deletions
|
@ -306,6 +306,9 @@ C_ASSERT(sizeof(CLIENTINFO) <= sizeof(((PTEB)0)->Win32ClientInfo));
|
||||||
/* Menu Item fType. */
|
/* Menu Item fType. */
|
||||||
#define MFT_RTOL 0x6000
|
#define MFT_RTOL 0x6000
|
||||||
|
|
||||||
|
/* Menu Item fState. */
|
||||||
|
#define MFS_HBMMENUBMP 0x20000000
|
||||||
|
|
||||||
typedef struct tagITEM
|
typedef struct tagITEM
|
||||||
{
|
{
|
||||||
UINT fType;
|
UINT fType;
|
||||||
|
|
|
@ -178,15 +178,7 @@ PMENU FASTCALL VerifyMenu(PMENU pMenu)
|
||||||
|
|
||||||
BOOL IntDestroyMenu( PMENU pMenu, BOOL bRecurse, BOOL RemoveFromProcess)
|
BOOL IntDestroyMenu( PMENU pMenu, BOOL bRecurse, BOOL RemoveFromProcess)
|
||||||
{
|
{
|
||||||
/* DestroyMenu should not destroy system menu popup owner */
|
PMENU SubMenu;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pMenu->rgItems) /* recursively destroy submenus */
|
if (pMenu->rgItems) /* recursively destroy submenus */
|
||||||
{
|
{
|
||||||
|
@ -194,33 +186,46 @@ BOOL IntDestroyMenu( PMENU pMenu, BOOL bRecurse, BOOL RemoveFromProcess)
|
||||||
ITEM *item = pMenu->rgItems;
|
ITEM *item = pMenu->rgItems;
|
||||||
for (i = pMenu->cItems; i > 0; i--, item++)
|
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);
|
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);
|
GreSetObjectOwner(item->hbmp, GDI_OBJ_HMGR_POWNED);
|
||||||
item->spSubMenu = NULL;
|
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 );
|
DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems );
|
||||||
pMenu->rgItems = NULL;
|
pMenu->rgItems = NULL;
|
||||||
pMenu->cItems = 0; //// What ever~!
|
pMenu->cItems = 0;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntDestroyMenuObject(PMENU Menu,
|
IntDestroyMenuObject(PMENU Menu, BOOL bRecurse, BOOL RemoveFromProcess)
|
||||||
BOOL bRecurse, BOOL RemoveFromProcess)
|
|
||||||
{
|
{
|
||||||
if(Menu)
|
if(Menu)
|
||||||
{
|
{
|
||||||
PWND Window;
|
PWND Window;
|
||||||
|
|
||||||
/* Remove all menu items */
|
/* Remove all menu items */
|
||||||
IntDestroyMenu( Menu, bRecurse, RemoveFromProcess);
|
IntDestroyMenu( Menu, bRecurse, RemoveFromProcess);
|
||||||
|
|
||||||
if(RemoveFromProcess)
|
if (RemoveFromProcess)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&Menu->ListEntry);
|
RemoveEntryList(&Menu->ListEntry);
|
||||||
}
|
}
|
||||||
|
@ -234,9 +239,17 @@ IntDestroyMenuObject(PMENU Menu,
|
||||||
if (Window)
|
if (Window)
|
||||||
{
|
{
|
||||||
Window->IDMenu = 0;
|
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);
|
ret = UserDeleteObject(Menu->head.h, TYPE_MENU);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{ // Make sure it is really dead or just marked for deletion.
|
{ // Make sure it is really dead or just marked for deletion.
|
||||||
|
@ -338,7 +351,7 @@ PITEM FASTCALL MENU_FindItem( PMENU *pmenu, UINT *nPos, UINT wFlags )
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntRemoveMenuItem( PMENU pMenu, UINT nPos, UINT wFlags, BOOL bRecurse )
|
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);
|
TRACE("(menu=%p pos=%04x flags=%04x)\n",pMenu, nPos, wFlags);
|
||||||
if (!(item = MENU_FindItem( &pMenu, &nPos, wFlags ))) return FALSE;
|
if (!(item = MENU_FindItem( &pMenu, &nPos, wFlags ))) return FALSE;
|
||||||
|
@ -364,10 +377,7 @@ IntRemoveMenuItem( PMENU pMenu, UINT nPos, UINT wFlags, BOOL bRecurse )
|
||||||
item++;
|
item++;
|
||||||
nPos++;
|
nPos++;
|
||||||
}
|
}
|
||||||
NewItems = DesktopHeapAlloc(pMenu->head.rpdesk, pMenu->cItems * sizeof(ITEM));
|
pMenu->rgItems = DesktopHeapReAlloc(pMenu->head.rpdesk, pMenu->rgItems, pMenu->cItems * sizeof(ITEM));
|
||||||
RtlCopyMemory(NewItems, pMenu->rgItems, pMenu->cItems * sizeof(ITEM));
|
|
||||||
DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems);
|
|
||||||
pMenu->rgItems = NewItems;
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -819,6 +829,10 @@ IntSetMenuItemInfo(PMENU MenuObject, PITEM MenuItem, PROSMENUITEMINFO lpmii, PUN
|
||||||
if(lpmii->fMask & MIIM_BITMAP)
|
if(lpmii->fMask & MIIM_BITMAP)
|
||||||
{
|
{
|
||||||
MenuItem->hbmp = lpmii->hbmpItem;
|
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)
|
if(lpmii->fMask & MIIM_CHECKMARKS)
|
||||||
{
|
{
|
||||||
|
@ -858,6 +872,7 @@ IntSetMenuItemInfo(PMENU MenuObject, PITEM MenuItem, PROSMENUITEMINFO lpmii, PUN
|
||||||
ERR("Pop Up Menu Double Trouble!\n");
|
ERR("Pop Up Menu Double Trouble!\n");
|
||||||
SubMenuObject = IntCreateMenu(&hMenu, FALSE); // It will be marked.
|
SubMenuObject = IntCreateMenu(&hMenu, FALSE); // It will be marked.
|
||||||
if (!SubMenuObject) return FALSE;
|
if (!SubMenuObject) return FALSE;
|
||||||
|
IntReleaseMenuObject(SubMenuObject); // This will be referenced again after insertion.
|
||||||
circref = TRUE;
|
circref = TRUE;
|
||||||
}
|
}
|
||||||
if ( MENU_depth( SubMenuObject, 0) > MAXMENUDEPTH )
|
if ( MENU_depth( SubMenuObject, 0) > MAXMENUDEPTH )
|
||||||
|
|
Loading…
Reference in a new issue