You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
5.5 KiB
208 lines
5.5 KiB
/**************************** Module Header ********************************\
|
|
* Module Name: mnapi.c
|
|
*
|
|
* Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
*
|
|
* Rarely Used Menu API Functions
|
|
*
|
|
* History:
|
|
* 10-10-90 JimA Cleanup.
|
|
* 03-18-91 IanJa Window revaliodation added
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
/***************************************************************************\
|
|
* xxxSetMenu
|
|
*
|
|
* Sets the given window's menu to the menu specified by the pMenu
|
|
* parameter. If pMenu is Null, the window's current menu is removed (but
|
|
* not destroyed).
|
|
*
|
|
* History:
|
|
\***************************************************************************/
|
|
|
|
BOOL xxxSetMenu(
|
|
PWND pwnd,
|
|
PMENU pMenu,
|
|
BOOL fRedraw)
|
|
{
|
|
CheckLock(pwnd);
|
|
CheckLock(pMenu);
|
|
|
|
if (!TestwndChild(pwnd)) {
|
|
|
|
LockWndMenu(pwnd, &pwnd->spmenu, pMenu);
|
|
|
|
/*
|
|
* only redraw the frame if the window is non-minimized --
|
|
* even if it's not visible, we need RedrawFrame to recalc the NC size
|
|
*
|
|
* Added a check for (redraw) since the MDISetMenu() only needs to
|
|
* set the menu and not perform any redraws.
|
|
*/
|
|
if (!TestWF(pwnd, WFMINIMIZED) && fRedraw)
|
|
xxxRedrawFrame(pwnd);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
RIPERR0(ERROR_CHILD_WINDOW_MENU, RIP_VERBOSE, "");
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* xxxSetSystemMenu
|
|
*
|
|
* !
|
|
*
|
|
* History:
|
|
\***************************************************************************/
|
|
|
|
BOOL xxxSetSystemMenu(
|
|
PWND pwnd,
|
|
PMENU pMenu)
|
|
{
|
|
CheckLock(pwnd);
|
|
CheckLock(pMenu);
|
|
|
|
if (TestWF(pwnd, WFSYSMENU)) {
|
|
PMENU pmenuT = pwnd->spmenuSys;
|
|
if (LockWndMenu(pwnd, &pwnd->spmenuSys, pMenu))
|
|
_DestroyMenu(pmenuT);
|
|
|
|
MNPositionSysMenu(pwnd, pMenu);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
RIPERR0(ERROR_NO_SYSTEM_MENU, RIP_VERBOSE, "");
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* xxxSetDialogSystemMenu
|
|
*
|
|
* !
|
|
*
|
|
* History:
|
|
\***************************************************************************/
|
|
|
|
BOOL xxxSetDialogSystemMenu(
|
|
PWND pwnd)
|
|
{
|
|
PMENU pMenu;
|
|
|
|
CheckLock(pwnd);
|
|
|
|
pMenu = pwnd->head.rpdesk->spmenuDialogSys;
|
|
if (pMenu == NULL) {
|
|
#ifdef LAME_BUTTON
|
|
pMenu = xxxLoadSysDesktopMenu (&pwnd->head.rpdesk->spmenuDialogSys, ID_DIALOGSYSMENU, pwnd);
|
|
#else
|
|
pMenu = xxxLoadSysDesktopMenu (&pwnd->head.rpdesk->spmenuDialogSys, ID_DIALOGSYSMENU);
|
|
#endif // LAME_BUTTON
|
|
}
|
|
|
|
LockWndMenu(pwnd, &pwnd->spmenuSys, pMenu);
|
|
|
|
return (pMenu != NULL);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* xxxEndMenu
|
|
*
|
|
* !
|
|
* Revalidation notes:
|
|
* o xxxEndMenu must be called with a valid non-NULL pwnd.
|
|
* o Revalidation is not required in this routine: pwnd is used at the start
|
|
* to obtain pMenuState, and not used again.
|
|
*
|
|
* History:
|
|
\***************************************************************************/
|
|
|
|
void xxxEndMenu(
|
|
PMENUSTATE pMenuState)
|
|
{
|
|
BOOL fMenuStateOwner;
|
|
PPOPUPMENU ppopup;
|
|
PTHREADINFO ptiCurrent;
|
|
|
|
if ((ppopup = pMenuState->pGlobalPopupMenu) == NULL) {
|
|
|
|
/*
|
|
* We're not really in menu mode. This can happen
|
|
* if we are forced out of menu loop too soon; i.e, from
|
|
* inside xxxMNGetPopup or xxxTrackPopupMenuEx.
|
|
*/
|
|
UserAssert(!pMenuState->fInsideMenuLoop && !pMenuState->fMenuStarted);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
pMenuState->fInsideMenuLoop = FALSE;
|
|
pMenuState->fMenuStarted = FALSE;
|
|
/*
|
|
* Mark the popup as destroyed so people will not use it anymore.
|
|
* This means that root popups can be marked as destroyed before
|
|
* actually being destroyed (nice and confusing).
|
|
*/
|
|
ppopup->fDestroyed = TRUE;
|
|
|
|
/*
|
|
* Determine if this is the menu loop owner before calling back.
|
|
* Only the owner can destroy the menu windows
|
|
*/
|
|
ptiCurrent = PtiCurrent();
|
|
fMenuStateOwner = (ptiCurrent == pMenuState->ptiMenuStateOwner);
|
|
|
|
/*
|
|
* Release mouse capture if we got it in xxxStartMenuState
|
|
*/
|
|
if (ptiCurrent->pq->spwndCapture == pMenuState->pGlobalPopupMenu->spwndNotify) {
|
|
xxxMNReleaseCapture();
|
|
}
|
|
|
|
/*
|
|
* Bail if this is not the menu loop owner
|
|
*/
|
|
if (!fMenuStateOwner) {
|
|
RIPMSG1(RIP_WARNING, "xxxEndMenu: Thread %#p doesn't own the menu loop", ptiCurrent);
|
|
return;
|
|
}
|
|
/*
|
|
* If the menu loop is running on a thread different than the thread
|
|
* that owns spwndNotify, we can have two threads trying to end
|
|
* this menu at the same time.
|
|
*/
|
|
if (pMenuState->fInEndMenu) {
|
|
RIPMSG1(RIP_WARNING, "xxxEndMenu: already in EndMenu. pMenuState:%#p", pMenuState);
|
|
return;
|
|
}
|
|
pMenuState->fInEndMenu = TRUE;
|
|
|
|
if (pMenuState->pGlobalPopupMenu->spwndNotify != NULL) {
|
|
if (!pMenuState->pGlobalPopupMenu->fInCancel) {
|
|
xxxMNDismiss(pMenuState);
|
|
}
|
|
} else {
|
|
BOOL fTrackedPopup = ppopup->fIsTrackPopup;
|
|
|
|
/*
|
|
* This should do the same stuff as MenuCancelMenus but not send any
|
|
* messages...
|
|
*/
|
|
xxxMNCloseHierarchy(ppopup, pMenuState);
|
|
|
|
if (fTrackedPopup) {
|
|
xxxDestroyWindow(ppopup->spwndPopupMenu);
|
|
}
|
|
|
|
}
|
|
|
|
}
|