📄 stdafx.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 + -