⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdafx.h

📁 用VC开发ACTIVEX 一书 实例2 ATLServer
💻 H
字号:
// stdafx.h : include file for standard system include files,
//      or project specific include files that are used frequently,
//      but are changed infrequently

#if !defined(AFX_STDAFX_H__03699605_809E_11D0_BEFF_00400538977D__INCLUDED_)
#define AFX_STDAFX_H__03699605_809E_11D0_BEFF_00400538977D__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define STRICT

#include <afxwin.h>
#include <afxdisp.h>

#define _WIN32_WINNT 0x0400
#define _ATL_APARTMENT_THREADED


#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include <atlcom.h>

// ****** ATL 2.0 version - Added by Jerry Anderson for shared object support
// **
#define DECLARE_NOT_AGGREGATABLE_SHARED(cBase, clsid) public:\
	typedef CComCreator2< CComCreator< CComObjectShared<cBase, clsid> >, CComFailCreator<CLASS_E_NOAGGREGATION> > _CreatorClass;

// if this object was registered and the refcount is 1 (which is from the "RegisterActiveObject")
// then revoke the registration so the object can be destroyed properly - The AddRef/Release pair
// is to protect the destruction and prevent the object from being deleted before we are out of this call
// since the RevokeActiveObject is going to call "Release" also and the refcount would be 0 if we didn't AddRef 

#define RELEASE_AND_DESTROY_SHARED() \
	InternalRelease(); \
if(dwRegister && m_dwRef == 1) \
	{ InternalAddRef(); DWORD dwtRegID = dwRegister; dwRegister = 0; ::RevokeActiveObject(dwtRegID, NULL); InternalRelease(); } \
if(m_dwRef == 0) \
	{ delete this; return 0; } \
return m_dwRef

//Base is the user's class that derives from CComObjectRoot and whatever
//interfaces the user wants to support on the object
template <class cBase, const CLSID * clsid>
class CComObjectShared : public cBase
{
public:
	// this is here to prevent an ASSERT when executing	"InternalFinalConstructRelease()"
	DECLARE_PROTECT_FINAL_CONSTRUCT();
	ULONG dwRegister;
	typedef cBase _BaseClass;
	CComObjectShared(void* = NULL)
	{
		// protect the construction
		this->InternalAddRef();

		// lock down the application so it does not fall out from under us
		_Module.Lock();

		// clear the member
		dwRegister = NULL;

		// Initialize an IUnknown reference
		LPUNKNOWN pIUnknown = NULL;
			
		// QI for the IUnknown
		if(_InternalQueryInterface(IID_IUnknown, (void **) &pIUnknown) == S_OK)
		{
			// register the clsid as an active object so other applications will get the same object
			if(::RegisterActiveObject(pIUnknown, *clsid, ACTIVEOBJECT_STRONG, &dwRegister) != S_OK)
				// clear the member
				dwRegister = NULL;

			// release the IUnknown
			pIUnknown->Release();
		}

		// protect the construction
		this->InternalRelease();
	}
	virtual ~CComObjectShared()
	{
		// Set refcount to 1 to protect destruction
		m_dwRef = 1L; 
		FinalRelease(); 
		_Module.Unlock();
	}

	//If InternalAddRef or InteralRelease is undefined then your class
	//doesn't derive from CComObjectRoot
	STDMETHOD_(ULONG, AddRef)() 
	{
		// release the IUnknown reference
		return InternalAddRef();
	}
	STDMETHOD_(ULONG, Release)()
	{
		RELEASE_AND_DESTROY_SHARED();
	}
	//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
	STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
	{return _InternalQueryInterface(iid, ppvObject);}
	static HRESULT WINAPI CreateInstance(CComObjectShared<cBase, clsid>** pp);
};

// needed for ATL version 1.1
// template <class cBase, const CLSID * clsid> 
// CComObjectShared<cBase, clsid>* CComObjectShared<cBase, clsid>::pSharedObject = NULL;

template <class cBase, const CLSID * clsid>
HRESULT WINAPI CComObjectShared<cBase, clsid>::CreateInstance(CComObjectShared<cBase, clsid>** pp)
{
	_ASSERTE(pp != NULL);
	HRESULT hRes = E_OUTOFMEMORY;

	CComObjectShared<cBase, clsid>* p = NULL;
	ATLTRY((p = new CComObjectShared<cBase, clsid>()))
	if (p != NULL)
	{
		p->SetVoid(NULL);
		p->InternalFinalConstructAddRef();
		hRes = p->FinalConstruct();
		// this line differs from the original code - 
		// for some reason the reference counts
		// for the object are not correct when created this way
		p->InternalAddRef();
		p->InternalFinalConstructRelease();
		if (hRes != S_OK)
		{
			delete p;
			p = NULL;
		}
	}
	*pp = p;

	return hRes;
}

// **
// ****** ATL 2.0 version - Added by Jerry Anderson for shared object support

// ****** ATL 2.0 version - Added by Jerry Anderson for single instance object support 
// **
#define DECLARE_NOT_AGGREGATABLE_SINGLE(cBase, clsid, iBase, iid) public:\
	typedef CComCreator2< CComCreatorSingle< CComObjectSingle<cBase, clsid, iBase, iid>, clsid>, CComFailCreator<CLASS_E_NOAGGREGATION> > _CreatorClass;

// if this object was registered and the refcount is 1 (which is from the "RegisterActiveObject")
// then revoke the registration so the object can be destroyed properly - The AddRef/Release pair
// is to protect the destruction and prevent the object from being deleted before we are out of this call
// since the RevokeActiveObject is going to call "Release" also and the refcount would be 0 if we didn't AddRef 

#define RELEASE_AND_DESTROY_SINGLE() \
	InternalRelease(); \
if(dwRegister && m_dwRef == 1) \
	{ InternalAddRef(); DWORD dwtRegID = dwRegister; dwRegister = 0; ::RevokeActiveObject(dwtRegID, NULL); InternalRelease(); } \
if(m_dwRef == 0) \
	{ delete this; return 0; } \
return m_dwRef

//Base is the user's class that derives from CComObjectRoot and whatever
//interfaces the user wants to support on the object
template <class cBase, const CLSID * clsid, class iBase, const IID * iid>
class CComObjectSingle : public cBase
{
public:
	// this is here to prevent an ASSERT when executing	"InternalFinalConstructRelease()"
	DECLARE_PROTECT_FINAL_CONSTRUCT();
	ULONG dwRegister;
	typedef cBase _BaseClass;
	CComObjectSingle(void* = NULL)
	{
		// protect the construction
		this->InternalAddRef();

		// lock down the application so it does not fall out from under us
		_Module.Lock();

		// clear the member
		dwRegister = NULL;

		// Initialize an IUnknown reference
		LPUNKNOWN pIUnknown = NULL;
			
		// se if the object is already running
		::GetActiveObject(*clsid, NULL, &pIUnknown);

		// if we didn't get a reference to a running object
		if(!pIUnknown)
		{
			// QI for the IUnknown
			if(_InternalQueryInterface(IID_IUnknown, (void **) &pIUnknown) == S_OK)
			{
				// register the clsid as an active object so other applications will get the same object
				::RegisterActiveObject(pIUnknown, *clsid, ACTIVEOBJECT_STRONG, &dwRegister);

				// release the IUnknown
				pIUnknown->Release();
			}

			// clear the reference just to be safe
			pIUnknown = NULL;	
		}
		else
			// release the IUnknown
			pIUnknown->Release();

		// protect the construction
		this->InternalRelease();
	}
	virtual ~CComObjectSingle()
	{
		// Set refcount to 1 to protect destruction
		m_dwRef = 1L; 
		FinalRelease(); 
		_Module.Unlock();
	}

	//If InternalAddRef or InteralRelease is undefined then your class
	//doesn't derive from CComObjectRoot
	STDMETHOD_(ULONG, AddRef)() 
	{
		// release the IUnknown reference
		return InternalAddRef();
	}
	STDMETHOD_(ULONG, Release)()
	{
		RELEASE_AND_DESTROY_SINGLE();
	}
	//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
	STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
	{return _InternalQueryInterface(iid, ppvObject);}
	static HRESULT WINAPI CreateInstance(CComObjectSingle<cBase, clsid, iBase, iid>** pp);
};

// needed for ATL version 1.1
// template <class cBase, const CLSID * clsid, class iBase, const IID * iid> 
// CComObjectSingle<cBase, clsid, iBase, iid>* CComObjectSingle<cBase, clsid, iBase, iid>::pSingleObject = NULL;

template <class cBase, const CLSID * clsid, class iBase, const IID * iid>
HRESULT WINAPI CComObjectSingle<cBase, clsid, iBase, iid>::CreateInstance(CComObjectSingle<cBase, clsid, iBase, iid>** pp)
{
	_ASSERTE(pp != NULL);
	HRESULT hRes = E_OUTOFMEMORY;

	// Initialize an IUnknown reference
	LPUNKNOWN pIUnknown = NULL;
		
	// se if the object is already running
	::GetActiveObject(*clsid, NULL, &pIUnknown);

	// if we didn't get a reference to a running object
	if(!pIUnknown)
	{
		CComObjectSingle<cBase, clsid, iBase, iid>* p = NULL;
		ATLTRY((p = new CComObjectSingle<cBase, clsid, iBase, iid>()))
		if (p != NULL)
		{
			p->SetVoid(NULL);
			p->InternalFinalConstructAddRef();
			hRes = p->FinalConstruct();
			// this line differs from the original code - for some reason the reference counts
			// for the object are not correct when created this way
			p->InternalAddRef();
			p->InternalFinalConstructRelease();
			if (hRes != S_OK)
			{
				delete p;
				p = NULL;
			}
		}
		*pp = p;
	}
	else
	{
		// get a pointer
		iBase * piBase = NULL;

		// QI for the interface
		pIUnknown->QueryInterface(*iid, (LPVOID*) &piBase);

		// cast the interface pointer to the class
		*pp = (CComObjectSingle<cBase, clsid, iBase, iid>*) piBase;

		// release the IUnknown reference
		pIUnknown->Release();
	}

	return hRes;
}

template <class T1, const CLSID* clsid>
class CComCreatorSingle
{
public:
	static HRESULT PASCAL CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
	{
		_ASSERTE(*ppv == NULL);
		HRESULT hRes = E_OUTOFMEMORY;

		// Initialize an IUnknown reference
		LPUNKNOWN pIUnknown = NULL;
			
		// se if the object is already running
		::GetActiveObject(*clsid, NULL, &pIUnknown);

		// if we didn't get a reference to a running object
		if(!pIUnknown)
		{
			T1* p = NULL;
			ATLTRY(p = new T1(pv))
			if (p != NULL)
			{
				p->SetVoid(pv);
				p->InternalFinalConstructAddRef();
				hRes = p->FinalConstruct();
				p->InternalFinalConstructRelease();
				if (hRes == S_OK)
					hRes = p->QueryInterface(riid, ppv);
				if (hRes != S_OK)
					delete p;
			}
		}
		else
		{
			// get the IID that was requested
			hRes = pIUnknown->QueryInterface(riid, ppv);

			// release the IUnknown reference
			pIUnknown->Release();
		}
		return hRes;
	}
};

// **
// ****** ATL 2.0 version - Added by Jerry Anderson for single instance object support

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__03699605_809E_11D0_BEFF_00400538977D__INCLUDED)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -