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

  1. /**************************** Module Header ********************************\
  2. * Module Name: mnapi.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * Rarely Used Menu API Functions
  7. *
  8. * History:
  9. * 10-10-90 JimA Cleanup.
  10. * 03-18-91 IanJa Window revaliodation added
  11. \***************************************************************************/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. /***************************************************************************\
  15. * xxxSetMenu
  16. *
  17. * Sets the given window's menu to the menu specified by the pMenu
  18. * parameter. If pMenu is Null, the window's current menu is removed (but
  19. * not destroyed).
  20. *
  21. * History:
  22. \***************************************************************************/
  23. BOOL xxxSetMenu(
  24. PWND pwnd,
  25. PMENU pMenu,
  26. BOOL fRedraw)
  27. {
  28. CheckLock(pwnd);
  29. CheckLock(pMenu);
  30. if (!TestwndChild(pwnd)) {
  31. LockWndMenu(pwnd, &pwnd->spmenu, pMenu);
  32. /*
  33. * only redraw the frame if the window is non-minimized --
  34. * even if it's not visible, we need RedrawFrame to recalc the NC size
  35. *
  36. * Added a check for (redraw) since the MDISetMenu() only needs to
  37. * set the menu and not perform any redraws.
  38. */
  39. if (!TestWF(pwnd, WFMINIMIZED) && fRedraw)
  40. xxxRedrawFrame(pwnd);
  41. return TRUE;
  42. }
  43. RIPERR0(ERROR_CHILD_WINDOW_MENU, RIP_VERBOSE, "");
  44. return FALSE;
  45. }
  46. /***************************************************************************\
  47. * xxxSetSystemMenu
  48. *
  49. * !
  50. *
  51. * History:
  52. \***************************************************************************/
  53. BOOL xxxSetSystemMenu(
  54. PWND pwnd,
  55. PMENU pMenu)
  56. {
  57. CheckLock(pwnd);
  58. CheckLock(pMenu);
  59. if (TestWF(pwnd, WFSYSMENU)) {
  60. PMENU pmenuT = pwnd->spmenuSys;
  61. if (LockWndMenu(pwnd, &pwnd->spmenuSys, pMenu))
  62. _DestroyMenu(pmenuT);
  63. MNPositionSysMenu(pwnd, pMenu);
  64. return TRUE;
  65. }
  66. RIPERR0(ERROR_NO_SYSTEM_MENU, RIP_VERBOSE, "");
  67. return FALSE;
  68. }
  69. /***************************************************************************\
  70. * xxxSetDialogSystemMenu
  71. *
  72. * !
  73. *
  74. * History:
  75. \***************************************************************************/
  76. BOOL xxxSetDialogSystemMenu(
  77. PWND pwnd)
  78. {
  79. PMENU pMenu;
  80. CheckLock(pwnd);
  81. pMenu = pwnd->head.rpdesk->spmenuDialogSys;
  82. if (pMenu == NULL) {
  83. #ifdef LAME_BUTTON
  84. pMenu = xxxLoadSysDesktopMenu (&pwnd->head.rpdesk->spmenuDialogSys, ID_DIALOGSYSMENU, pwnd);
  85. #else
  86. pMenu = xxxLoadSysDesktopMenu (&pwnd->head.rpdesk->spmenuDialogSys, ID_DIALOGSYSMENU);
  87. #endif // LAME_BUTTON
  88. }
  89. LockWndMenu(pwnd, &pwnd->spmenuSys, pMenu);
  90. return (pMenu != NULL);
  91. }
  92. /***************************************************************************\
  93. * xxxEndMenu
  94. *
  95. * !
  96. * Revalidation notes:
  97. * o xxxEndMenu must be called with a valid non-NULL pwnd.
  98. * o Revalidation is not required in this routine: pwnd is used at the start
  99. * to obtain pMenuState, and not used again.
  100. *
  101. * History:
  102. \***************************************************************************/
  103. void xxxEndMenu(
  104. PMENUSTATE pMenuState)
  105. {
  106. BOOL fMenuStateOwner;
  107. PPOPUPMENU ppopup;
  108. PTHREADINFO ptiCurrent;
  109. if ((ppopup = pMenuState->pGlobalPopupMenu) == NULL) {
  110. /*
  111. * We're not really in menu mode. This can happen
  112. * if we are forced out of menu loop too soon; i.e, from
  113. * inside xxxMNGetPopup or xxxTrackPopupMenuEx.
  114. */
  115. UserAssert(!pMenuState->fInsideMenuLoop && !pMenuState->fMenuStarted);
  116. return;
  117. }
  118. pMenuState->fInsideMenuLoop = FALSE;
  119. pMenuState->fMenuStarted = FALSE;
  120. /*
  121. * Mark the popup as destroyed so people will not use it anymore.
  122. * This means that root popups can be marked as destroyed before
  123. * actually being destroyed (nice and confusing).
  124. */
  125. ppopup->fDestroyed = TRUE;
  126. /*
  127. * Determine if this is the menu loop owner before calling back.
  128. * Only the owner can destroy the menu windows
  129. */
  130. ptiCurrent = PtiCurrent();
  131. fMenuStateOwner = (ptiCurrent == pMenuState->ptiMenuStateOwner);
  132. /*
  133. * Release mouse capture if we got it in xxxStartMenuState
  134. */
  135. if (ptiCurrent->pq->spwndCapture == pMenuState->pGlobalPopupMenu->spwndNotify) {
  136. xxxMNReleaseCapture();
  137. }
  138. /*
  139. * Bail if this is not the menu loop owner
  140. */
  141. if (!fMenuStateOwner) {
  142. RIPMSG1(RIP_WARNING, "xxxEndMenu: Thread %#p doesn't own the menu loop", ptiCurrent);
  143. return;
  144. }
  145. /*
  146. * If the menu loop is running on a thread different than the thread
  147. * that owns spwndNotify, we can have two threads trying to end
  148. * this menu at the same time.
  149. */
  150. if (pMenuState->fInEndMenu) {
  151. RIPMSG1(RIP_WARNING, "xxxEndMenu: already in EndMenu. pMenuState:%#p", pMenuState);
  152. return;
  153. }
  154. pMenuState->fInEndMenu = TRUE;
  155. if (pMenuState->pGlobalPopupMenu->spwndNotify != NULL) {
  156. if (!pMenuState->pGlobalPopupMenu->fInCancel) {
  157. xxxMNDismiss(pMenuState);
  158. }
  159. } else {
  160. BOOL fTrackedPopup = ppopup->fIsTrackPopup;
  161. /*
  162. * This should do the same stuff as MenuCancelMenus but not send any
  163. * messages...
  164. */
  165. xxxMNCloseHierarchy(ppopup, pMenuState);
  166. if (fTrackedPopup) {
  167. xxxDestroyWindow(ppopup->spwndPopupMenu);
  168. }
  169. }
  170. }