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 >
Wrap
C/C++ Source or Header
|
1998-06-16
|
5KB
|
208 lines
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#ifdef AFXCTL_OLE_SEG
#pragma code_seg(AFXCTL_OLE_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#ifndef _AFX_NO_OLE_SUPPORT
/////////////////////////////////////////////////////////////////////////////
// Signature for verb functions
typedef BOOL (AFX_MSG_CALL CCmdTarget::*AFX_PVERBFN)(LPMSG, HWND, LPCRECT);
/////////////////////////////////////////////////////////////////////////////
// CEnumOleVerb - enumerator for OLEVERB
class CEnumOleVerb : public CEnumArray
{
public:
CEnumOleVerb(const void* pvEnum, UINT nSize) :
CEnumArray(sizeof(OLEVERB), pvEnum, nSize, TRUE) {}
~CEnumOleVerb();
protected:
virtual BOOL OnNext(void* pv);
DECLARE_INTERFACE_MAP()
};
BEGIN_INTERFACE_MAP(CEnumOleVerb, CEnumArray)
INTERFACE_PART(CEnumOleVerb, IID_IEnumOLEVERB, EnumVOID)
END_INTERFACE_MAP()
CEnumOleVerb::~CEnumOleVerb()
{
if (m_pClonedFrom == NULL)
{
UINT iVerb;
LPOLEVERB lpVerb = (LPOLEVERB)(void*)m_pvEnum;
for (iVerb = 0; iVerb < m_nSize; iVerb++)
CoTaskMemFree(lpVerb[iVerb].lpszVerbName);
}
// destructor will free the actual array (if it was not a clone)
}
BOOL CEnumOleVerb::OnNext(void* pv)
{
if (!CEnumArray::OnNext(pv))
return FALSE;
// outgoing OLEVERB requires the verb name to be copied
// (the caller has responsibility to free it)
LPOLEVERB lpVerb = (LPOLEVERB)pv;
if (lpVerb->lpszVerbName != NULL)
{
lpVerb->lpszVerbName = AfxAllocTaskOleString(lpVerb->lpszVerbName);
if (lpVerb->lpszVerbName == NULL)
AfxThrowMemoryException();
}
// otherwise, copying worked...
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CCmdTarget::EnumOleVerbs - implementation for IOleObject::EnumVerbs
BOOL CCmdTarget::EnumOleVerbs(LPENUMOLEVERB* ppenumOleVerb)
{
LPOLEVERB lpVerbList = NULL;
LPOLEVERB lpVerbListNew;
LPOLEVERB lpVerb;
long nVerbs = 0;
long nAlloc = 0;
CString strVerbName;
// walk the chain of message maps
const AFX_MSGMAP* pMessageMap;
const AFX_MSGMAP_ENTRY* lpEntry;
for (pMessageMap = GetMessageMap();
(pMessageMap != NULL);
#ifdef _AFXDLL
pMessageMap = pMessageMap->pfnGetBaseMap())
#else
pMessageMap = pMessageMap->pBaseMap)
#endif
{
// find all verb entries in the map that have non-negative IDs
lpEntry = pMessageMap->lpEntries;
while ((lpEntry = AfxFindMessageEntry(lpEntry, 0xC002, 0, 1)) != NULL)
{
ASSERT(lpEntry != NULL);
if (nVerbs == nAlloc)
{
// not enough space for new item -- allocate more
lpVerbListNew = new OLEVERB[nVerbs + 10];
nAlloc += 10;
memcpy(lpVerbListNew, lpVerbList, (size_t)(nVerbs *
sizeof(OLEVERB)));
delete [] lpVerbList;
lpVerbList = lpVerbListNew;
}
// get the string for this item
if (!strVerbName.LoadString(lpEntry->nSig))
strVerbName = _T("<unknown verb>"); // LoadString failed
ASSERT(strVerbName.GetLength() > 0);
// add this item to the list
ASSERT(nVerbs < nAlloc);
lpVerb = &lpVerbList[nVerbs];
lpVerb->lVerb = nVerbs;
lpVerb->lpszVerbName = AfxAllocTaskOleString(strVerbName);
lpVerb->fuFlags = 0;
lpVerb->grfAttribs = OLEVERBATTRIB_ONCONTAINERMENU;
++nVerbs;
++lpEntry;
}
}
if (nVerbs > 0)
{
// create and return the IEnumOLEVERB object
CEnumOleVerb* pEnum = new CEnumOleVerb(lpVerbList, (UINT)nVerbs);
*ppenumOleVerb = (IEnumOLEVERB*)&pEnum->m_xEnumVOID;
}
else
{
// no verbs: return NULL
*ppenumOleVerb = NULL;
}
return (nVerbs > 0);
}
/////////////////////////////////////////////////////////////////////////////
// CCmdTarget::DoOleVerb - implementation for IOleObject::DoVerb
BOOL CCmdTarget::DoOleVerb(LONG iVerb, LPMSG lpMsg, HWND hWndParent,
LPCRECT lpRect)
{
const AFX_MSGMAP* pMessageMap;
const AFX_MSGMAP_ENTRY* lpEntry = NULL;
long i = -1;
for (pMessageMap = GetMessageMap();
(pMessageMap != NULL) && (lpEntry == NULL);
#ifdef _AFXDLL
pMessageMap = pMessageMap->pfnGetBaseMap())
#else
pMessageMap = pMessageMap->pBaseMap)
#endif
{
if (iVerb < 0) // Standard verb (negative index)
{
lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, 0xC002, 0,
(UINT)iVerb);
}
else // Non-standard verb (non-negative index)
{
lpEntry = pMessageMap->lpEntries;
while (((lpEntry = AfxFindMessageEntry(lpEntry, 0xC002, 0, 1)) !=
NULL) && (++i < iVerb))
{
++lpEntry;
}
ASSERT((lpEntry == NULL) || (i == iVerb));
}
}
if (lpEntry == NULL)
return FALSE;
AFX_PVERBFN pfn = (AFX_PVERBFN)(lpEntry->pfn);
if (!(this->*pfn)(lpMsg, hWndParent, lpRect))
THROW (new CException);
return TRUE;
}
#endif //!_AFX_NO_OLE_SUPPORT
/////////////////////////////////////////////////////////////////////////////
// Force any extra compiler-generated code into AFX_INIT_SEG
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif