Leaked source code of windows server 2003
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

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