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.
 
 
 
 
 
 

213 lines
6.3 KiB

/****************************** Module Header ******************************\
* Module Name: menu.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* This module contains common menu functions.
*
* History:
* 11-15-94 JimA Created.
\***************************************************************************/
/***************************************************************************\
* GetMenuDefaultItem
*
* Searches through a menu for the default item. A menu can have at most
* one default. We will return either the ID or the position, as requested.
*
* We try to return back the first non-disabled default item. However, if
* all of the defaults we encountered were disabled, we'll return back the
* the first default if we found it.
*
\***************************************************************************/
DWORD _GetMenuDefaultItem(
PMENU pMenu,
BOOL fByPosition,
UINT uFlags)
{
int iItem, cItems;
PITEM pItem;
PMENU pSubMenu;
pItem = REBASEALWAYS(pMenu, rgItems);
cItems = pMenu->cItems;
/*
* Walk the list of items sequentially until we find one that has
* MFS_DEFAULT set.
*/
for (iItem = 0; iItem < cItems; iItem++, pItem++) {
if (TestMFS(pItem, MFS_DEFAULT)) {
if ((uFlags & GMDI_USEDISABLED) || !TestMFS(pItem, MFS_GRAYED)) {
if ((uFlags & GMDI_GOINTOPOPUPS) && (pItem->spSubMenu != NULL)) {
DWORD id;
/*
* Is there a valid submenu default? If not, we'll use
* this one.
*/
pSubMenu = REBASEPTR(pMenu, pItem->spSubMenu);
id = _GetMenuDefaultItem(pSubMenu, fByPosition, uFlags);
if (id != MFMWFP_NOITEM)
return id;
}
break;
}
}
}
if (iItem < cItems) {
return (fByPosition ? iItem : pItem->wID);
} else {
return MFMWFP_NOITEM;
}
}
/***************************************************************************\
* xxxMNCanClose
*
* Returns TRUE if the given window either doesn't have a system menu or has
* a system menu which has an enabled menu item with the SC_CLOSE syscommand
* id.
*
\***************************************************************************/
BOOL xxxMNCanClose(
PWND pwnd)
{
PMENU pMenu;
PITEM pItem;
PCLS pcls;
CheckLock(pwnd);
pcls = (PCLS)REBASEALWAYS(pwnd, pcls);
if (TestCF2(pcls, CFNOCLOSE)) {
return FALSE;
}
pMenu = xxxGetSysMenuHandle(pwnd);
if (!pMenu || !(pMenu = REBASEPTR(pwnd, pMenu))) {
return FALSE;
}
/*
* Note how this parallels the code in SetCloseDefault -- we check for
* 3 different IDs.
*/
pItem = MNLookUpItem(pMenu, SC_CLOSE, FALSE, NULL);
if (!pItem) {
pItem = MNLookUpItem(pMenu, SC_CLOSE-0x7000, FALSE, NULL);
if (!pItem) {
pItem = MNLookUpItem(pMenu, 0xC070, FALSE, NULL);
}
}
return (pItem && !TestMFS(pItem, MFS_GRAYED));
}
/***************************************************************************\
* xxxLoadSysMenu
*
* Loads a menu from USER32.DLL and then gives it the "NT5 look".
*
* History
* 04/02/97 GerardoB Created.
* 06/28/00 JasonSch Added code to add menu item for the lame button.
\***************************************************************************/
RTLMENU xxxLoadSysMenu(
#ifdef LAME_BUTTON
UINT uMenuId,
PWND pwnd)
#else
UINT uMenuId)
#endif // LAME_BUTTON
{
RTLMENU rtlMenu;
MENUINFO mi;
MENUITEMINFO mii;
TL tlMenu;
#ifdef _USERK_
UNICODE_STRING strMenuName;
RtlInitUnicodeStringOrId(&strMenuName, MAKEINTRESOURCE(uMenuId));
rtlMenu = xxxClientLoadMenu(NULL, &strMenuName);
#else
rtlMenu = LoadMenu(hmodUser, MAKEINTRESOURCE(uMenuId));
#endif // _USERK_
if (rtlMenu == NULL) {
RIPMSG1(RIP_WARNING, "xxxLoadSysMenu failed to load: %#lx", uMenuId);
return NULL;
}
ThreadLockAlways(rtlMenu, &tlMenu);
/*
* Add the checkorbmp style (draw bitmaps and checkmarks on the
* same column).
*/
mi.cbSize = sizeof(mi);
mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS;
mi.dwStyle = MNS_CHECKORBMP;
xxxRtlSetMenuInfo(rtlMenu, &mi);
/*
* Add the bitmaps for close, minimize, maximize and restore items.
*/
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_BITMAP;
mii.hbmpItem = HBMMENU_POPUP_CLOSE;
xxxRtlSetMenuItemInfo(rtlMenu, SC_CLOSE, &mii);
if (uMenuId != ID_DIALOGSYSMENU) {
mii.hbmpItem = HBMMENU_POPUP_MINIMIZE;
xxxRtlSetMenuItemInfo (rtlMenu, SC_MINIMIZE, &mii);
mii.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
xxxRtlSetMenuItemInfo (rtlMenu, SC_MAXIMIZE, &mii);
mii.hbmpItem = HBMMENU_POPUP_RESTORE;
xxxRtlSetMenuItemInfo (rtlMenu, SC_RESTORE, &mii);
}
#ifdef LAME_BUTTON
if (pwnd && TestWF(pwnd, WEFLAMEBUTTON)) {
/*
* We want to add a lame button item to the this window's system menu.
*
* The menuitem is added to the beginning of the menu, and then a
* separator is added after it.
*/
RTLMENU rtlSubMenu = RtlGetSubMenu(rtlMenu, 0);
PMENU pSubMenu;
#ifdef _USERK_
pSubMenu = rtlSubMenu;
#else
pSubMenu = VALIDATEHMENU(rtlSubMenu);
#endif // _USERK_
if (pSubMenu != NULL) {
UNICODE_STRING strItem;
TL tlmenu;
RtlInitUnicodeString(&strItem, gpsi->gwszLame);
RtlZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mi);
mii.fMask = MIIM_TYPE;
mii.fType = MFT_SEPARATOR;
ThreadLockAlways(rtlSubMenu, &tlmenu);
xxxRtlInsertMenuItem(rtlSubMenu, 0, TRUE, &mii, &strItem);
mii.fType = 0;
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STRING;
mii.dwTypeData = strItem.Buffer;
mii.wID = SC_LAMEBUTTON;
xxxRtlInsertMenuItem(rtlSubMenu, 0, TRUE, &mii, &strItem);
ThreadUnlock(&tlmenu);
}
}
#endif // LAME_BUTTON
ThreadUnlock(&tlMenu);
return rtlMenu;
}