oleverb.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 AFXCTL_OLE_SEG
  12. #pragma code_seg(AFXCTL_OLE_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. #ifndef _AFX_NO_OLE_SUPPORT
  20. /////////////////////////////////////////////////////////////////////////////
  21. // Signature for verb functions
  22. typedef BOOL (AFX_MSG_CALL CCmdTarget::*AFX_PVERBFN)(LPMSG, HWND, LPCRECT);
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CEnumOleVerb - enumerator for OLEVERB
  25. class CEnumOleVerb : public CEnumArray
  26. {
  27. public:
  28. CEnumOleVerb(const void* pvEnum, UINT nSize) :
  29. CEnumArray(sizeof(OLEVERB), pvEnum, nSize, TRUE) {}
  30. ~CEnumOleVerb();
  31. protected:
  32. virtual BOOL OnNext(void* pv);
  33. DECLARE_INTERFACE_MAP()
  34. };
  35. BEGIN_INTERFACE_MAP(CEnumOleVerb, CEnumArray)
  36. INTERFACE_PART(CEnumOleVerb, IID_IEnumOLEVERB, EnumVOID)
  37. END_INTERFACE_MAP()
  38. CEnumOleVerb::~CEnumOleVerb()
  39. {
  40. if (m_pClonedFrom == NULL)
  41. {
  42. UINT iVerb;
  43. LPOLEVERB lpVerb = (LPOLEVERB)(void*)m_pvEnum;
  44. for (iVerb = 0; iVerb < m_nSize; iVerb++)
  45. CoTaskMemFree(lpVerb[iVerb].lpszVerbName);
  46. }
  47. // destructor will free the actual array (if it was not a clone)
  48. }
  49. BOOL CEnumOleVerb::OnNext(void* pv)
  50. {
  51. if (!CEnumArray::OnNext(pv))
  52. return FALSE;
  53. // outgoing OLEVERB requires the verb name to be copied
  54. // (the caller has responsibility to free it)
  55. LPOLEVERB lpVerb = (LPOLEVERB)pv;
  56. if (lpVerb->lpszVerbName != NULL)
  57. {
  58. lpVerb->lpszVerbName = AfxAllocTaskOleString(lpVerb->lpszVerbName);
  59. if (lpVerb->lpszVerbName == NULL)
  60. AfxThrowMemoryException();
  61. }
  62. // otherwise, copying worked...
  63. return TRUE;
  64. }
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CCmdTarget::EnumOleVerbs - implementation for IOleObject::EnumVerbs
  67. BOOL CCmdTarget::EnumOleVerbs(LPENUMOLEVERB* ppenumOleVerb)
  68. {
  69. LPOLEVERB lpVerbList = NULL;
  70. LPOLEVERB lpVerbListNew;
  71. LPOLEVERB lpVerb;
  72. long nVerbs = 0;
  73. long nAlloc = 0;
  74. CString strVerbName;
  75. // walk the chain of message maps
  76. const AFX_MSGMAP* pMessageMap;
  77. const AFX_MSGMAP_ENTRY* lpEntry;
  78. for (pMessageMap = GetMessageMap();
  79. (pMessageMap != NULL);
  80. #ifdef _AFXDLL
  81. pMessageMap = pMessageMap->pfnGetBaseMap())
  82. #else
  83. pMessageMap = pMessageMap->pBaseMap)
  84. #endif
  85. {
  86. // find all verb entries in the map that have non-negative IDs
  87. lpEntry = pMessageMap->lpEntries;
  88. while ((lpEntry = AfxFindMessageEntry(lpEntry, 0xC002, 0, 1)) != NULL)
  89. {
  90. ASSERT(lpEntry != NULL);
  91. if (nVerbs == nAlloc)
  92. {
  93. // not enough space for new item -- allocate more
  94. lpVerbListNew = new OLEVERB[nVerbs + 10];
  95. nAlloc += 10;
  96. memcpy(lpVerbListNew, lpVerbList, (size_t)(nVerbs *
  97. sizeof(OLEVERB)));
  98. delete [] lpVerbList;
  99. lpVerbList = lpVerbListNew;
  100. }
  101. // get the string for this item
  102. if (!strVerbName.LoadString(lpEntry->nSig))
  103. strVerbName = _T("<unknown verb>"); // LoadString failed
  104. ASSERT(strVerbName.GetLength() > 0);
  105. // add this item to the list
  106. ASSERT(nVerbs < nAlloc);
  107. lpVerb = &lpVerbList[nVerbs];
  108. lpVerb->lVerb = nVerbs;
  109. lpVerb->lpszVerbName = AfxAllocTaskOleString(strVerbName);
  110. lpVerb->fuFlags = 0;
  111. lpVerb->grfAttribs = OLEVERBATTRIB_ONCONTAINERMENU;
  112. ++nVerbs;
  113. ++lpEntry;
  114. }
  115. }
  116. if (nVerbs > 0)
  117. {
  118. // create and return the IEnumOLEVERB object
  119. CEnumOleVerb* pEnum = new CEnumOleVerb(lpVerbList, (UINT)nVerbs);
  120. *ppenumOleVerb = (IEnumOLEVERB*)&pEnum->m_xEnumVOID;
  121. }
  122. else
  123. {
  124. // no verbs: return NULL
  125. *ppenumOleVerb = NULL;
  126. }
  127. return (nVerbs > 0);
  128. }
  129. /////////////////////////////////////////////////////////////////////////////
  130. // CCmdTarget::DoOleVerb - implementation for IOleObject::DoVerb
  131. BOOL CCmdTarget::DoOleVerb(LONG iVerb, LPMSG lpMsg, HWND hWndParent,
  132. LPCRECT lpRect)
  133. {
  134. const AFX_MSGMAP* pMessageMap;
  135. const AFX_MSGMAP_ENTRY* lpEntry = NULL;
  136. long i = -1;
  137. for (pMessageMap = GetMessageMap();
  138. (pMessageMap != NULL) && (lpEntry == NULL);
  139. #ifdef _AFXDLL
  140. pMessageMap = pMessageMap->pfnGetBaseMap())
  141. #else
  142. pMessageMap = pMessageMap->pBaseMap)
  143. #endif
  144. {
  145. if (iVerb < 0) // Standard verb (negative index)
  146. {
  147. lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, 0xC002, 0,
  148. (UINT)iVerb);
  149. }
  150. else // Non-standard verb (non-negative index)
  151. {
  152. lpEntry = pMessageMap->lpEntries;
  153. while (((lpEntry = AfxFindMessageEntry(lpEntry, 0xC002, 0, 1)) !=
  154. NULL) && (++i < iVerb))
  155. {
  156. ++lpEntry;
  157. }
  158. ASSERT((lpEntry == NULL) || (i == iVerb));
  159. }
  160. }
  161. if (lpEntry == NULL)
  162. return FALSE;
  163. AFX_PVERBFN pfn = (AFX_PVERBFN)(lpEntry->pfn);
  164. if (!(this->*pfn)(lpMsg, hWndParent, lpRect))
  165. THROW (new CException);
  166. return TRUE;
  167. }
  168. #endif //!_AFX_NO_OLE_SUPPORT
  169. /////////////////////////////////////////////////////////////////////////////
  170. // Force any extra compiler-generated code into AFX_INIT_SEG
  171. #ifdef AFX_INIT_SEG
  172. #pragma code_seg(AFX_INIT_SEG)
  173. #endif