winmenu.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_CORE1_SEG
  12. #pragma code_seg(AFX_CORE1_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. /////////////////////////////////////////////////////////////////////////////
  20. // Map from HMENU to CMenu *
  21. #include "fixalloc.h"
  22. class CTempMenu : public CMenu
  23. {
  24. DECLARE_DYNCREATE(CTempMenu)
  25. DECLARE_FIXED_ALLOC(CTempMenu);
  26. };
  27. CHandleMap* PASCAL afxMapHMENU(BOOL bCreate)
  28. {
  29. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  30. if (pState->m_pmapHMENU == NULL && bCreate)
  31. {
  32. BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  33. #ifndef _AFX_PORTABLE
  34. _PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
  35. #endif
  36. pState->m_pmapHMENU = new CHandleMap(RUNTIME_CLASS(CTempMenu),
  37. offsetof(CMenu, m_hMenu)),
  38. #ifndef _AFX_PORTABLE
  39. AfxSetNewHandler(pnhOldHandler);
  40. #endif
  41. AfxEnableMemoryTracking(bEnable);
  42. }
  43. return pState->m_pmapHMENU;
  44. }
  45. CMenu* PASCAL CMenu::FromHandle(HMENU hMenu)
  46. {
  47. CHandleMap* pMap = afxMapHMENU(TRUE); // create map if not exist
  48. ASSERT(pMap != NULL);
  49. CMenu* pMenu = (CMenu*)pMap->FromHandle(hMenu);
  50. ASSERT(pMenu == NULL || pMenu->m_hMenu == hMenu);
  51. return pMenu;
  52. }
  53. CMenu* PASCAL CMenu::FromHandlePermanent(HMENU hMenu)
  54. {
  55. CHandleMap* pMap = afxMapHMENU();
  56. CMenu* pMenu = NULL;
  57. if (pMap != NULL)
  58. {
  59. // only look in the permanent map - does no allocations
  60. pMenu = (CMenu*)pMap->LookupPermanent(hMenu);
  61. ASSERT(pMenu == NULL || pMenu->m_hMenu == hMenu);
  62. }
  63. return pMenu;
  64. }
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CMenu
  67. #ifdef _DEBUG
  68. void CMenu::AssertValid() const
  69. {
  70. CObject::AssertValid();
  71. ASSERT(m_hMenu == NULL || ::IsMenu(m_hMenu));
  72. }
  73. void CMenu::Dump(CDumpContext& dc) const
  74. {
  75. CObject::Dump(dc);
  76. dc << "m_hMenu = " << (UINT)m_hMenu;
  77. dc << "\n";
  78. }
  79. #endif
  80. BOOL CMenu::Attach(HMENU hMenu)
  81. {
  82. ASSERT(m_hMenu == NULL); // only attach once, detach on destroy
  83. if (hMenu == NULL)
  84. return FALSE;
  85. CHandleMap* pMap = afxMapHMENU(TRUE); // create map if not exist
  86. ASSERT(pMap != NULL);
  87. pMap->SetPermanent(m_hMenu = hMenu, this);
  88. return TRUE;
  89. }
  90. HMENU CMenu::Detach()
  91. {
  92. HMENU hMenu;
  93. if ((hMenu = m_hMenu) != NULL)
  94. {
  95. CHandleMap* pMap = afxMapHMENU(); // don't create if not exist
  96. if (pMap != NULL)
  97. pMap->RemoveHandle(m_hMenu);
  98. }
  99. m_hMenu = NULL;
  100. return hMenu;
  101. }
  102. BOOL CMenu::DestroyMenu()
  103. {
  104. if (m_hMenu == NULL)
  105. return FALSE;
  106. return ::DestroyMenu(Detach());
  107. }
  108. /////////////////////////////////////////////////////////////////////////////
  109. // Self-drawing menu items
  110. void CMenu::DrawItem(LPDRAWITEMSTRUCT /* lpDrawItemStruct */)
  111. {
  112. // default drawing does nothing
  113. }
  114. void CMenu::MeasureItem(LPMEASUREITEMSTRUCT /* lpMeasureItemStruct */)
  115. {
  116. // default drawing does nothing
  117. }
  118. #ifdef AFX_INIT_SEG
  119. #pragma code_seg(AFX_INIT_SEG)
  120. #endif
  121. IMPLEMENT_DYNCREATE(CMenu, CObject)
  122. IMPLEMENT_DYNCREATE(CTempMenu, CMenu);
  123. #pragma warning(disable: 4074)
  124. #pragma init_seg(compiler)
  125. IMPLEMENT_FIXED_ALLOC(CTempMenu, 64);
  126. /////////////////////////////////////////////////////////////////////////////