| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 | 
							- // 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 AFX_OLE_SEG
 
- #pragma code_seg(AFX_OLE_SEG)
 
- #endif
 
- #ifdef _DEBUG
 
- #undef THIS_FILE
 
- static char THIS_FILE[] = __FILE__;
 
- #endif
 
- #define new DEBUG_NEW
 
- /////////////////////////////////////////////////////////////////////////////
 
- // Debug helpers
 
- #ifdef _DEBUG
 
- // Helper for converting IID into useful string.  Only for debugging.
 
- LPCTSTR AFXAPI AfxGetIIDString(REFIID iid)
 
- {
 
- 	static TCHAR szUnfamiliar[80];
 
- 	TCHAR szByte[3];
 
- 	struct IID_ENTRY
 
- 	{
 
- 		const IID* piid;
 
- 		LPCTSTR lpszName;
 
- 	};
 
- #define MAKE_IID_ENTRY(name) { &name, _T(#name) }
 
- 	static const IID_ENTRY iidNameTable[] =
 
- 	{
 
- 		MAKE_IID_ENTRY(IID_IAdviseSink),
 
- 		MAKE_IID_ENTRY(IID_IAdviseSink2),
 
- 		MAKE_IID_ENTRY(IID_IBindCtx),
 
- 		MAKE_IID_ENTRY(IID_IClassFactory),
 
- 		MAKE_IID_ENTRY(IID_IContinueCallback),
 
- 		MAKE_IID_ENTRY(IID_IEnumOleDocumentViews),
 
- 		MAKE_IID_ENTRY(IID_IOleCommandTarget),
 
- 		MAKE_IID_ENTRY(IID_IOleDocument),
 
- 		MAKE_IID_ENTRY(IID_IOleDocumentSite),
 
- 		MAKE_IID_ENTRY(IID_IOleDocumentView),
 
- 		MAKE_IID_ENTRY(IID_IPrint),
 
- 		MAKE_IID_ENTRY(IID_IDataAdviseHolder),
 
- 		MAKE_IID_ENTRY(IID_IDataObject),
 
- 		MAKE_IID_ENTRY(IID_IDebug),
 
- 		MAKE_IID_ENTRY(IID_IDebugStream),
 
- 		MAKE_IID_ENTRY(IID_IDfReserved1),
 
- 		MAKE_IID_ENTRY(IID_IDfReserved2),
 
- 		MAKE_IID_ENTRY(IID_IDfReserved3),
 
- 		MAKE_IID_ENTRY(IID_IDispatch),
 
- 		MAKE_IID_ENTRY(IID_IDropSource),
 
- 		MAKE_IID_ENTRY(IID_IDropTarget),
 
- 		MAKE_IID_ENTRY(IID_IEnumCallback),
 
- 		MAKE_IID_ENTRY(IID_IEnumFORMATETC),
 
- 		MAKE_IID_ENTRY(IID_IEnumGeneric),
 
- 		MAKE_IID_ENTRY(IID_IEnumHolder),
 
- 		MAKE_IID_ENTRY(IID_IEnumMoniker),
 
- 		MAKE_IID_ENTRY(IID_IEnumOLEVERB),
 
- 		MAKE_IID_ENTRY(IID_IEnumSTATDATA),
 
- 		MAKE_IID_ENTRY(IID_IEnumSTATSTG),
 
- 		MAKE_IID_ENTRY(IID_IEnumString),
 
- 		MAKE_IID_ENTRY(IID_IEnumUnknown),
 
- 		MAKE_IID_ENTRY(IID_IEnumVARIANT),
 
- //      MAKE_IID_ENTRY(IID_IExternalConnection),
 
- 		MAKE_IID_ENTRY(IID_IInternalMoniker),
 
- 		MAKE_IID_ENTRY(IID_ILockBytes),
 
- 		MAKE_IID_ENTRY(IID_IMalloc),
 
- 		MAKE_IID_ENTRY(IID_IMarshal),
 
- 		MAKE_IID_ENTRY(IID_IMessageFilter),
 
- 		MAKE_IID_ENTRY(IID_IMoniker),
 
- 		MAKE_IID_ENTRY(IID_IOleAdviseHolder),
 
- 		MAKE_IID_ENTRY(IID_IOleCache),
 
- 		MAKE_IID_ENTRY(IID_IOleCache2),
 
- 		MAKE_IID_ENTRY(IID_IOleCacheControl),
 
- 		MAKE_IID_ENTRY(IID_IOleClientSite),
 
- 		MAKE_IID_ENTRY(IID_IOleContainer),
 
- 		MAKE_IID_ENTRY(IID_IOleInPlaceActiveObject),
 
- 		MAKE_IID_ENTRY(IID_IOleInPlaceFrame),
 
- 		MAKE_IID_ENTRY(IID_IOleInPlaceObject),
 
- 		MAKE_IID_ENTRY(IID_IOleInPlaceSite),
 
- 		MAKE_IID_ENTRY(IID_IOleInPlaceUIWindow),
 
- 		MAKE_IID_ENTRY(IID_IOleItemContainer),
 
- 		MAKE_IID_ENTRY(IID_IOleLink),
 
- 		MAKE_IID_ENTRY(IID_IOleManager),
 
- 		MAKE_IID_ENTRY(IID_IOleObject),
 
- 		MAKE_IID_ENTRY(IID_IOlePresObj),
 
- 		MAKE_IID_ENTRY(IID_IOleWindow),
 
- 		MAKE_IID_ENTRY(IID_IPSFactory),
 
- 		MAKE_IID_ENTRY(IID_IParseDisplayName),
 
- 		MAKE_IID_ENTRY(IID_IPersist),
 
- 		MAKE_IID_ENTRY(IID_IPersistFile),
 
- 		MAKE_IID_ENTRY(IID_IPersistStorage),
 
- 		MAKE_IID_ENTRY(IID_IPersistStream),
 
- 		MAKE_IID_ENTRY(IID_IProxyManager),
 
- 		MAKE_IID_ENTRY(IID_IRootStorage),
 
- 		MAKE_IID_ENTRY(IID_IRpcChannel),
 
- 		MAKE_IID_ENTRY(IID_IRpcProxy),
 
- 		MAKE_IID_ENTRY(IID_IRpcStub),
 
- 		MAKE_IID_ENTRY(IID_IRunnableObject),
 
- 		MAKE_IID_ENTRY(IID_IRunningObjectTable),
 
- 		MAKE_IID_ENTRY(IID_IStdMarshalInfo),
 
- 		MAKE_IID_ENTRY(IID_IStorage),
 
- 		MAKE_IID_ENTRY(IID_IStream),
 
- 		MAKE_IID_ENTRY(IID_IStubManager),
 
- 		MAKE_IID_ENTRY(IID_IUnknown),
 
- 		MAKE_IID_ENTRY(IID_IViewObject),
 
- 		MAKE_IID_ENTRY(IID_IViewObject2),
 
- 		MAKE_IID_ENTRY(IID_NULL),
 
- 	};
 
- #undef MAKE_IID_ENTRY
 
- 	// look for it in the table
 
- 	for (int i = 0; i < _countof(iidNameTable); i++)
 
- 	{
 
- 		if (iid == *iidNameTable[i].piid)
 
- 			return iidNameTable[i].lpszName;
 
- 	}
 
- 	// if we get here, it is some IID_ we haven't heard of...
 
- 	wsprintf(szUnfamiliar, _T("%8.8X-%4.4X-%4.4X-"),
 
- 		iid.Data1, iid.Data2, iid.Data3);
 
- 	for (int nIndex = 0; nIndex < 8; nIndex++)
 
- 	{
 
- 		wsprintf(szByte, _T("%2.2X"), iid.Data4[nIndex]);
 
- 		lstrcat(szUnfamiliar, szByte);
 
- 	}
 
- 	return szUnfamiliar;
 
- }
 
- #endif
 
- /////////////////////////////////////////////////////////////////////////////
 
- // Component object model helpers
 
- /////////////////////////////////////////////////////////////////////////////
 
- // IUnknown client helpers
 
- LPUNKNOWN AFXAPI _AfxQueryInterface(LPUNKNOWN lpUnknown, REFIID iid)
 
- {
 
- 	ASSERT(lpUnknown != NULL);
 
- 	LPUNKNOWN lpW = NULL;
 
- 	if (lpUnknown->QueryInterface(iid, (LPLP)&lpW) != S_OK)
 
- 		return NULL;
 
- 	return lpW;
 
- }
 
- DWORD AFXAPI _AfxRelease(LPUNKNOWN* lplpUnknown)
 
- {
 
- 	ASSERT(lplpUnknown != NULL);
 
- 	if (*lplpUnknown != NULL)
 
- 	{
 
- 		DWORD dwRef = (*lplpUnknown)->Release();
 
- 		*lplpUnknown = NULL;
 
- 		return dwRef;
 
- 	}
 
- 	return 0;
 
- }
 
- #define GetInterfacePtr(pTarget, pEntry) \
 
- 	((LPUNKNOWN)((BYTE*)pTarget + pEntry->nOffset))
 
- #define GetAggregatePtr(pTarget, pEntry) \
 
- 	(*(LPUNKNOWN*)((BYTE*)pTarget + pEntry->nOffset))
 
- /////////////////////////////////////////////////////////////////////////////
 
- // CCmdTarget interface map implementation
 
- // support for aggregation
 
- class CInnerUnknown : public IUnknown
 
- {
 
- public:
 
- 	STDMETHOD_(ULONG, AddRef)();
 
- 	STDMETHOD_(ULONG, Release)();
 
- 	STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppvObj);
 
- };
 
- // calling this function enables an object to be aggregatable
 
- void CCmdTarget::EnableAggregation()
 
- {
 
- 	// construct an CInnerUnknown just to get to the vtable
 
- 	CInnerUnknown innerUnknown;
 
- 	// copy the vtable & make sure initialized
 
- 	ASSERT(sizeof(m_xInnerUnknown) == sizeof(CInnerUnknown));
 
- 	m_xInnerUnknown = *(DWORD*)&innerUnknown;
 
- }
 
- DWORD CCmdTarget::ExternalAddRef()
 
- {
 
- 	// delegate to controlling unknown if aggregated
 
- 	if (m_pOuterUnknown != NULL)
 
- 		return m_pOuterUnknown->AddRef();
 
- 	return InternalAddRef();
 
- }
 
- DWORD CCmdTarget::InternalRelease()
 
- {
 
- 	ASSERT(GetInterfaceMap() != NULL);
 
- 	if (m_dwRef == 0)
 
- 		return 0;
 
- 	LONG lResult = InterlockedDecrement(&m_dwRef);
 
- 	if (lResult == 0)
 
- 	{
 
- 		AFX_MANAGE_STATE(m_pModuleState);
 
- 		OnFinalRelease();
 
- 	}
 
- 	return lResult;
 
- }
 
- DWORD CCmdTarget::ExternalRelease()
 
- {
 
- 	// delegate to controlling unknown if aggregated
 
- 	if (m_pOuterUnknown != NULL)
 
- 		return m_pOuterUnknown->Release();
 
- 	return InternalRelease();
 
- }
 
- // special QueryInterface used in implementation (does not AddRef)
 
- LPUNKNOWN CCmdTarget::GetInterface(const void* iid)
 
- {
 
- 	// allow general hook first chance
 
- 	LPUNKNOWN lpUnk;
 
- 	if ((lpUnk = GetInterfaceHook(iid)) != NULL)
 
- 		return lpUnk;
 
- 	const AFX_INTERFACEMAP* pMap = GetInterfaceMap();
 
- 	ASSERT(pMap != NULL);
 
- 	DWORD lData1 = ((IID*)iid)->Data1;
 
- 	// IUnknown is a special case since nobody really implements *only* it!
 
- 	BOOL bUnknown = ((DWORD*)&IID_IUnknown)[0] == lData1 &&
 
- 		((DWORD*)iid)[1] == ((DWORD*)&IID_IUnknown)[1] &&
 
- 		((DWORD*)iid)[2] == ((DWORD*)&IID_IUnknown)[2] &&
 
- 		((DWORD*)iid)[3] == ((DWORD*)&IID_IUnknown)[3];
 
- 	if (bUnknown)
 
- 	{
 
- 		do
 
- 		{
 
- 			const AFX_INTERFACEMAP_ENTRY* pEntry = pMap->pEntry;
 
- 			ASSERT(pEntry != NULL);
 
- 			while (pEntry->piid != NULL)
 
- 			{
 
- 				// check INTERFACE_ENTRY macro
 
- 				LPUNKNOWN lpUnk = GetInterfacePtr(this, pEntry);
 
- 				// check vtable pointer (can be NULL)
 
- 				if (*(DWORD*)lpUnk != 0)
 
- 					return lpUnk;
 
- 				// entry did not match -- keep looking
 
- 				++pEntry;
 
- 			}
 
- #ifdef _AFXDLL
 
- 		} while ((pMap = (*pMap->pfnGetBaseMap)()) != NULL);
 
- #else
 
- 		} while ((pMap = pMap->pBaseMap) != NULL);
 
- #endif
 
- 		// interface ID not found, fail the call
 
- 		return NULL;
 
- 	}
 
- 	// otherwise, walk the interface map to find the matching IID
 
- 	do
 
- 	{
 
- 		const AFX_INTERFACEMAP_ENTRY* pEntry = pMap->pEntry;
 
- 		ASSERT(pEntry != NULL);
 
- 		while (pEntry->piid != NULL)
 
- 		{
 
- 			if (((DWORD*)pEntry->piid)[0] == lData1 &&
 
- 				((DWORD*)pEntry->piid)[1] == ((DWORD*)iid)[1] &&
 
- 				((DWORD*)pEntry->piid)[2] == ((DWORD*)iid)[2] &&
 
- 				((DWORD*)pEntry->piid)[3] == ((DWORD*)iid)[3])
 
- 			{
 
- 				// check INTERFACE_ENTRY macro
 
- 				LPUNKNOWN lpUnk = GetInterfacePtr(this, pEntry);
 
- 				// check vtable pointer (can be NULL)
 
- 				if (*(DWORD*)lpUnk != 0)
 
- 					return lpUnk;
 
- 			}
 
- 			// entry did not match -- keep looking
 
- 			++pEntry;
 
- 		}
 
- #ifdef _AFXDLL
 
- 	} while ((pMap = (*pMap->pfnGetBaseMap)()) != NULL);
 
- #else
 
- 	} while ((pMap = pMap->pBaseMap) != NULL);
 
- #endif
 
- 	// interface ID not found, fail the call
 
- 	return NULL;
 
- }
 
- LPUNKNOWN CCmdTarget::QueryAggregates(const void* iid)
 
- {
 
- 	const AFX_INTERFACEMAP* pMap = GetInterfaceMap();
 
- 	ASSERT(pMap != NULL);
 
- 	// walk the Interface map to call aggregates
 
- 	do
 
- 	{
 
- 		const AFX_INTERFACEMAP_ENTRY* pEntry = pMap->pEntry;
 
- 		// skip non-aggregate entries
 
- 		ASSERT(pEntry != NULL);
 
- 		while (pEntry->piid != NULL)
 
- 			++pEntry;
 
- 		// call QueryInterface for each aggregate entry
 
- 		while (pEntry->nOffset != (size_t)-1)
 
- 		{
 
- 			LPUNKNOWN lpQuery = GetAggregatePtr(this, pEntry);
 
- 			// it is ok to have aggregate but not created yet
 
- 			if (lpQuery != NULL)
 
- 			{
 
- 				LPUNKNOWN lpUnk = NULL;
 
- 				if (lpQuery->QueryInterface(*(IID*)iid, (LPLP)&lpUnk)
 
- 					== S_OK && lpUnk != NULL)
 
- 				{
 
- 					// QueryInterface successful...
 
- 					return lpUnk;
 
- 				}
 
- 			}
 
- 			// entry did not match -- keep looking
 
- 			++pEntry;
 
- 		}
 
- #ifdef _AFXDLL
 
- 	} while ((pMap = (*pMap->pfnGetBaseMap)()) != NULL);
 
- #else
 
- 	} while ((pMap = pMap->pBaseMap) != NULL);
 
- #endif
 
- 	// interface ID not found, fail the call
 
- 	return NULL;
 
- }
 
- // real implementation of QueryInterface
 
- DWORD CCmdTarget::InternalQueryInterface(const void* iid, LPVOID* ppvObj)
 
- {
 
- 	// check local interfaces
 
- 	if ((*ppvObj = GetInterface(iid)) != NULL)
 
- 	{
 
- 		// interface was found -- add a reference
 
- 		ExternalAddRef();
 
- 		return S_OK;
 
- 	}
 
- 	// check aggregates
 
- 	if ((*ppvObj = QueryAggregates(iid)) != NULL)
 
- 		return S_OK;
 
- 	// interface ID not found, fail the call
 
- 	return (DWORD)E_NOINTERFACE;
 
- }
 
- // QueryInterface that is exported to normal clients
 
- DWORD CCmdTarget::ExternalQueryInterface(const void* iid,
 
- 	LPVOID* ppvObj)
 
- {
 
- 	// delegate to controlling unknown if aggregated
 
- 	if (m_pOuterUnknown != NULL)
 
- 		return m_pOuterUnknown->QueryInterface(*(IID*)iid, ppvObj);
 
- 	return InternalQueryInterface(iid, ppvObj);
 
- }
 
- /////////////////////////////////////////////////////////////////////////////
 
- // Inner IUnknown implementation (for aggregation)
 
- STDMETHODIMP_(ULONG) CInnerUnknown::AddRef()
 
- {
 
- 	METHOD_PROLOGUE_(CCmdTarget, InnerUnknown)
 
- 	return pThis->InternalAddRef();
 
- }
 
- STDMETHODIMP_(ULONG) CInnerUnknown::Release()
 
- {
 
- 	METHOD_PROLOGUE(CCmdTarget, InnerUnknown)
 
- 	return pThis->InternalRelease();
 
- }
 
- STDMETHODIMP CInnerUnknown::QueryInterface(REFIID iid, LPVOID* ppvObj)
 
- {
 
- 	METHOD_PROLOGUE_(CCmdTarget, InnerUnknown)
 
- 	if (iid == IID_IUnknown)
 
- 	{
 
- 		// QueryInterface on inner IUnknown for IID_IUnknown must
 
- 		//  return inner IUnknown.
 
- 		pThis->InternalAddRef();
 
- 		*ppvObj = this;
 
- 		return S_OK;
 
- 	}
 
- 	return pThis->InternalQueryInterface(&iid, ppvObj);
 
- }
 
- /////////////////////////////////////////////////////////////////////////////
 
- // other helper functions
 
- // ExternalDisconnect is used to remove RPC connections in destructors.  This
 
- //  insures that no RPC calls will go to the object after it has been
 
- //  deleted.
 
- void CCmdTarget::ExternalDisconnect()
 
- {
 
- 	if (m_dwRef == 0)   // already in disconnected state?
 
- 		return;
 
- 	// get IUnknown pointer for the object
 
- 	LPUNKNOWN lpUnknown = (LPUNKNOWN)GetInterface(&IID_IUnknown);
 
- 	ASSERT(lpUnknown != NULL);
 
- 	// disconnect the object
 
- 	InterlockedIncrement(&m_dwRef);  // protect object from destruction
 
- 	CoDisconnectObject(lpUnknown, 0);
 
- 	m_dwRef = 0;    // now in disconnected state
 
- }
 
- // GetControllingUnknown is used when creating aggregate objects,
 
- //  usually from OnCreateAggregates.  The outer, or controlling, unknown
 
- //  is one of the parameters to CoCreateInstance and other OLE creation
 
- //  functions which support aggregation.
 
- LPUNKNOWN CCmdTarget::GetControllingUnknown()
 
- {
 
- 	if (m_pOuterUnknown != NULL)
 
- 		return m_pOuterUnknown; // aggregate of m_pOuterUnknown
 
- 	LPUNKNOWN lpUnknown = (LPUNKNOWN)GetInterface(&IID_IUnknown);
 
- 	return lpUnknown;   // return our own IUnknown implementation
 
- }
 
- /////////////////////////////////////////////////////////////////////////////
 
- // Inline function declarations expanded out-of-line
 
- #ifndef _AFX_ENABLE_INLINES
 
- // expand inlines for OLE general APIs
 
- static char _szAfxOleInl[] = "afxole.inl";
 
- #undef THIS_FILE
 
- #define THIS_FILE _szAfxOleInl
 
- #define _AFXDISP_INLINE
 
- #include "afxole.inl"
 
- #endif //!_AFX_ENABLE_INLINES
 
- /////////////////////////////////////////////////////////////////////////////
 
 
  |