MENU.H
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // menu.h : menu merging implementation
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12. template <class T>
  13. class CMenu
  14. {
  15. public:
  16. void InPlaceMenuCreate()
  17. {
  18. IOleInPlaceFrame*   pFrame;
  19. HRESULT             hr;
  20. HMENU               hOurMenu;
  21. OLEMENUGROUPWIDTHS  mgw;
  22. T* pT = static_cast<T*>(this);
  23. if (pT->m_spInPlaceFrame == NULL)
  24. {
  25. // We weren't given an IOleInPlaceFrame pointer, so
  26. // we'll have to get it ourselves.
  27. OLEINPLACEFRAMEINFO frameInfo;
  28. RECT rcPos, rcClip;
  29. CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  30. frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  31. pT->m_spInPlaceSite->GetWindowContext(&pFrame,
  32. &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
  33. }
  34. else
  35. pFrame = pT->m_spInPlaceFrame;
  36. ZeroMemory(&mgw, sizeof(OLEMENUGROUPWIDTHS));
  37. // Create a blank menu and ask the container to add
  38. // its menus into the OLEMENUGROUPWIDTHS structure
  39. m_hMenuShared = ::CreateMenu();
  40. hr = pFrame->InsertMenus(m_hMenuShared, &mgw);
  41. if (FAILED(hr))
  42. {
  43. ::DestroyMenu(m_hMenuShared);
  44. m_hMenuShared = NULL;
  45. return;
  46. }
  47. // Insert our menus
  48. hOurMenu = LoadMenu(_Module.GetResourceInstance(),
  49. MAKEINTRESOURCE(IDR_MAINMENU));
  50. MergeMenus(m_hMenuShared, hOurMenu, &mgw.width[0], 1);
  51. DestroyMenu(hOurMenu);
  52. // Send the menu to the client
  53. m_hOleMenu = (HMENU)OleCreateMenuDescriptor(m_hMenuShared, &mgw);
  54. pFrame->SetMenu(m_hMenuShared, m_hOleMenu, pT->m_hWnd);
  55. // If we got the IOleInPlaceFrame pointer ourselves
  56. // we have to release it
  57. if (pT->m_spInPlaceFrame == NULL)
  58. pFrame->Release();
  59. }
  60. void InPlaceMenuDestroy()
  61. {
  62. T* pT = static_cast<T*>(this);
  63. CComPtr<IOleInPlaceFrame> spInPlaceFrame;
  64. CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  65. OLEINPLACEFRAMEINFO frameInfo;
  66. RECT rcPos, rcClip;
  67. // Get the clients IOleInPlaceFrame so we can ask
  68. // it to remove its menu
  69. pT->m_spInPlaceSite->GetWindowContext(&spInPlaceFrame,
  70. &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
  71. if (spInPlaceFrame)
  72. spInPlaceFrame->SetMenu(NULL, NULL, NULL);
  73. OleDestroyMenuDescriptor(m_hOleMenu);
  74. m_hOleMenu = NULL;
  75. HMENU hOurMenu = LoadMenu(_Module.GetResourceInstance(),
  76. MAKEINTRESOURCE(IDR_MAINMENU));
  77. UnmergeMenus(m_hMenuShared, hOurMenu);
  78. DestroyMenu(hOurMenu);
  79. }
  80. void MergeMenus(HMENU hMenuShared, HMENU hMenuSource, LONG* lpMenuWidths,
  81. int nWidthIndex)
  82. {
  83. // Copy the popups from the pMenuSource
  84. int nMenuItems = GetMenuItemCount(hMenuSource);
  85. int nGroupWidth = 0;
  86. int nPosition = 0;
  87. // Insert at appropriate spot depending on nWidthIndex
  88. ATLASSERT(nWidthIndex == 0 || nWidthIndex == 1);
  89. if (nWidthIndex == 1)
  90. nPosition = (int)lpMenuWidths[0];
  91. for (int i = 0; i < nMenuItems; i++)
  92. {
  93. // Get the HMENU of the popup
  94. HMENU hMenuPopup = ::GetSubMenu(hMenuSource, i);
  95. // Separators move us to next group
  96. UINT state = GetMenuState(hMenuSource, i, MF_BYPOSITION);
  97. if (hMenuPopup == NULL && (state & MF_SEPARATOR) != 0)
  98. {
  99.    // Servers should not touch past 5
  100. ATLASSERT(nWidthIndex <= 5);
  101. lpMenuWidths[nWidthIndex] = nGroupWidth;
  102. nGroupWidth = 0;
  103. if (nWidthIndex < 5)
  104. nPosition += (int)lpMenuWidths[nWidthIndex+1];
  105. nWidthIndex += 2;
  106. }
  107. else
  108. {
  109. // Get the menu item text
  110. TCHAR szItemText[256];
  111. int nLen = GetMenuString(hMenuSource, i, szItemText,
  112. sizeof szItemText, MF_BYPOSITION);
  113. // Popups are handled differently than normal menu items
  114. if (hMenuPopup != NULL)
  115. {
  116. if (::GetMenuItemCount(hMenuPopup) != 0)
  117. {
  118. // Strip the HIBYTE because it contains a count of items
  119. state = LOBYTE(state) | MF_POPUP;   // Must be popup
  120. // Non-empty popup -- add it to the shared menu bar
  121. InsertMenu(hMenuShared, nPosition, state | MF_BYPOSITION,
  122. (UINT)hMenuPopup, szItemText);
  123. ++nPosition;
  124. ++nGroupWidth;
  125. }
  126. }
  127. else if (nLen > 0)
  128. {
  129. // only non-empty items are added
  130. ATLASSERT(szItemText[0] != 0);
  131. // here the state does not contain a count in the HIBYTE
  132. InsertMenu(hMenuShared, nPosition, state | MF_BYPOSITION,
  133. GetMenuItemID(hMenuSource, i), szItemText);
  134. ++nPosition;
  135. ++nGroupWidth;
  136. }
  137. }
  138. }
  139. }
  140. void UnmergeMenus(HMENU hMenuShared, HMENU hMenuSource)
  141. {
  142. int cOurItems = GetMenuItemCount(hMenuSource);
  143. int cMenuItems = GetMenuItemCount(hMenuShared);
  144. for (int i = cMenuItems-1; i >= 0; i--)
  145. {
  146. // Check the popup menus
  147. HMENU hMenuPopup = ::GetSubMenu(hMenuShared, i);
  148. if (hMenuPopup != NULL)
  149. {
  150. // If it is one of ours, remove it from the hMenuShared
  151. for (int j = 0; j < cOurItems; j++)
  152. {
  153. if (::GetSubMenu(hMenuSource, j) == hMenuPopup)
  154. {
  155. // Remove the menu from hMenuShared
  156. RemoveMenu(hMenuShared, i, MF_BYPOSITION);
  157. break;
  158. }
  159. }
  160. }
  161. }
  162. }
  163. protected:
  164. HMENU   m_hOleMenu;
  165. HMENU   m_hMenuShared;
  166. };