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

  1. /****************************** Module Header ******************************\
  2. * Module Name: menu.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * This module contains common menu functions.
  7. *
  8. * History:
  9. * 11-15-94 JimA Created.
  10. \***************************************************************************/
  11. /***************************************************************************\
  12. * GetMenuDefaultItem
  13. *
  14. * Searches through a menu for the default item. A menu can have at most
  15. * one default. We will return either the ID or the position, as requested.
  16. *
  17. * We try to return back the first non-disabled default item. However, if
  18. * all of the defaults we encountered were disabled, we'll return back the
  19. * the first default if we found it.
  20. *
  21. \***************************************************************************/
  22. DWORD _GetMenuDefaultItem(
  23. PMENU pMenu,
  24. BOOL fByPosition,
  25. UINT uFlags)
  26. {
  27. int iItem, cItems;
  28. PITEM pItem;
  29. PMENU pSubMenu;
  30. pItem = REBASEALWAYS(pMenu, rgItems);
  31. cItems = pMenu->cItems;
  32. /*
  33. * Walk the list of items sequentially until we find one that has
  34. * MFS_DEFAULT set.
  35. */
  36. for (iItem = 0; iItem < cItems; iItem++, pItem++) {
  37. if (TestMFS(pItem, MFS_DEFAULT)) {
  38. if ((uFlags & GMDI_USEDISABLED) || !TestMFS(pItem, MFS_GRAYED)) {
  39. if ((uFlags & GMDI_GOINTOPOPUPS) && (pItem->spSubMenu != NULL)) {
  40. DWORD id;
  41. /*
  42. * Is there a valid submenu default? If not, we'll use
  43. * this one.
  44. */
  45. pSubMenu = REBASEPTR(pMenu, pItem->spSubMenu);
  46. id = _GetMenuDefaultItem(pSubMenu, fByPosition, uFlags);
  47. if (id != MFMWFP_NOITEM)
  48. return id;
  49. }
  50. break;
  51. }
  52. }
  53. }
  54. if (iItem < cItems) {
  55. return (fByPosition ? iItem : pItem->wID);
  56. } else {
  57. return MFMWFP_NOITEM;
  58. }
  59. }
  60. /***************************************************************************\
  61. * xxxMNCanClose
  62. *
  63. * Returns TRUE if the given window either doesn't have a system menu or has
  64. * a system menu which has an enabled menu item with the SC_CLOSE syscommand
  65. * id.
  66. *
  67. \***************************************************************************/
  68. BOOL xxxMNCanClose(
  69. PWND pwnd)
  70. {
  71. PMENU pMenu;
  72. PITEM pItem;
  73. PCLS pcls;
  74. CheckLock(pwnd);
  75. pcls = (PCLS)REBASEALWAYS(pwnd, pcls);
  76. if (TestCF2(pcls, CFNOCLOSE)) {
  77. return FALSE;
  78. }
  79. pMenu = xxxGetSysMenuHandle(pwnd);
  80. if (!pMenu || !(pMenu = REBASEPTR(pwnd, pMenu))) {
  81. return FALSE;
  82. }
  83. /*
  84. * Note how this parallels the code in SetCloseDefault -- we check for
  85. * 3 different IDs.
  86. */
  87. pItem = MNLookUpItem(pMenu, SC_CLOSE, FALSE, NULL);
  88. if (!pItem) {
  89. pItem = MNLookUpItem(pMenu, SC_CLOSE-0x7000, FALSE, NULL);
  90. if (!pItem) {
  91. pItem = MNLookUpItem(pMenu, 0xC070, FALSE, NULL);
  92. }
  93. }
  94. return (pItem && !TestMFS(pItem, MFS_GRAYED));
  95. }
  96. /***************************************************************************\
  97. * xxxLoadSysMenu
  98. *
  99. * Loads a menu from USER32.DLL and then gives it the "NT5 look".
  100. *
  101. * History
  102. * 04/02/97 GerardoB Created.
  103. * 06/28/00 JasonSch Added code to add menu item for the lame button.
  104. \***************************************************************************/
  105. RTLMENU xxxLoadSysMenu(
  106. #ifdef LAME_BUTTON
  107. UINT uMenuId,
  108. PWND pwnd)
  109. #else
  110. UINT uMenuId)
  111. #endif // LAME_BUTTON
  112. {
  113. RTLMENU rtlMenu;
  114. MENUINFO mi;
  115. MENUITEMINFO mii;
  116. TL tlMenu;
  117. #ifdef _USERK_
  118. UNICODE_STRING strMenuName;
  119. RtlInitUnicodeStringOrId(&strMenuName, MAKEINTRESOURCE(uMenuId));
  120. rtlMenu = xxxClientLoadMenu(NULL, &strMenuName);
  121. #else
  122. rtlMenu = LoadMenu(hmodUser, MAKEINTRESOURCE(uMenuId));
  123. #endif // _USERK_
  124. if (rtlMenu == NULL) {
  125. RIPMSG1(RIP_WARNING, "xxxLoadSysMenu failed to load: %#lx", uMenuId);
  126. return NULL;
  127. }
  128. ThreadLockAlways(rtlMenu, &tlMenu);
  129. /*
  130. * Add the checkorbmp style (draw bitmaps and checkmarks on the
  131. * same column).
  132. */
  133. mi.cbSize = sizeof(mi);
  134. mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS;
  135. mi.dwStyle = MNS_CHECKORBMP;
  136. xxxRtlSetMenuInfo(rtlMenu, &mi);
  137. /*
  138. * Add the bitmaps for close, minimize, maximize and restore items.
  139. */
  140. mii.cbSize = sizeof(mii);
  141. mii.fMask = MIIM_BITMAP;
  142. mii.hbmpItem = HBMMENU_POPUP_CLOSE;
  143. xxxRtlSetMenuItemInfo(rtlMenu, SC_CLOSE, &mii);
  144. if (uMenuId != ID_DIALOGSYSMENU) {
  145. mii.hbmpItem = HBMMENU_POPUP_MINIMIZE;
  146. xxxRtlSetMenuItemInfo (rtlMenu, SC_MINIMIZE, &mii);
  147. mii.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
  148. xxxRtlSetMenuItemInfo (rtlMenu, SC_MAXIMIZE, &mii);
  149. mii.hbmpItem = HBMMENU_POPUP_RESTORE;
  150. xxxRtlSetMenuItemInfo (rtlMenu, SC_RESTORE, &mii);
  151. }
  152. #ifdef LAME_BUTTON
  153. if (pwnd && TestWF(pwnd, WEFLAMEBUTTON)) {
  154. /*
  155. * We want to add a lame button item to the this window's system menu.
  156. *
  157. * The menuitem is added to the beginning of the menu, and then a
  158. * separator is added after it.
  159. */
  160. RTLMENU rtlSubMenu = RtlGetSubMenu(rtlMenu, 0);
  161. PMENU pSubMenu;
  162. #ifdef _USERK_
  163. pSubMenu = rtlSubMenu;
  164. #else
  165. pSubMenu = VALIDATEHMENU(rtlSubMenu);
  166. #endif // _USERK_
  167. if (pSubMenu != NULL) {
  168. UNICODE_STRING strItem;
  169. TL tlmenu;
  170. RtlInitUnicodeString(&strItem, gpsi->gwszLame);
  171. RtlZeroMemory(&mii, sizeof(mii));
  172. mii.cbSize = sizeof(mi);
  173. mii.fMask = MIIM_TYPE;
  174. mii.fType = MFT_SEPARATOR;
  175. ThreadLockAlways(rtlSubMenu, &tlmenu);
  176. xxxRtlInsertMenuItem(rtlSubMenu, 0, TRUE, &mii, &strItem);
  177. mii.fType = 0;
  178. mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STRING;
  179. mii.dwTypeData = strItem.Buffer;
  180. mii.wID = SC_LAMEBUTTON;
  181. xxxRtlInsertMenuItem(rtlSubMenu, 0, TRUE, &mii, &strItem);
  182. ThreadUnlock(&tlmenu);
  183. }
  184. }
  185. #endif // LAME_BUTTON
  186. ThreadUnlock(&tlMenu);
  187. return rtlMenu;
  188. }