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
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;
|
|
}
|