home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / oleverb.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  5KB  |  208 lines

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