|
|
/**************************** 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); }
}
}
|