www.pudn.com > Aggregation.zip > Cmpnt2.cpp


// 
// Cmpnt2.cpp - Component 2 
//   Note the changes in the class factory marked with @N. 
// 
#include  
#include  
 
#include "..\Agrregation\Component\Iface.h" 
#include "..\Agrregation\Component\Registry.h" 
 
void trace(const char* msg) { cout << "Component 2:\t" << msg << endl ;} 
 
/////////////////////////////////////////////////////////// 
// 
// Global variables 
// 
 
// Static variables 
static HMODULE g_hModule = NULL ;   // DLL module handle 
static long g_cComponents = 0 ;     // Count of active components 
static long g_cServerLocks = 0 ;    // Count of locks 
 
// Friendly name of component 
const char g_szFriendlyName[] 
	= "YNTest, Component 2" ; 
 
// Version-independent ProgID 
const char g_szVerIndProgID[] = "YNTest.Cmpnt2" ; 
 
// ProgID 
const char g_szProgID[] = "YNTest.Cmpnt2.1" ; 
 
/////////////////////////////////////////////////////////// 
// 
// Nondelegating IUnknown interface  @N 
// 
struct INondelegatingUnknown 
{ 
	virtual HRESULT __stdcall 
		NondelegatingQueryInterface(const IID&, void**) = 0 ; 
	virtual ULONG __stdcall NondelegatingAddRef() = 0 ; 
	virtual ULONG __stdcall NondelegatingRelease() = 0 ; 
} ; 
 
/////////////////////////////////////////////////////////// 
// 
// Component  
// 
class CB : public IY, 
           public INondelegatingUnknown 
{ 
public: 
	// Delegating IUnknown 
	virtual HRESULT __stdcall 
		QueryInterface(const IID& iid, void** ppv) 
	{ 
		trace("代理接口 QueryInterface.") ; 
		return m_pUnknownOuter->QueryInterface(iid, ppv) ;  
		//else 
		//	return NondelegatingQueryInterface(iid,ppv); 
	} 
 
	virtual ULONG __stdcall AddRef()  
	{ 
		trace("代理接口 AddRef.") ; 
	//	if (m_pUnknownOuter != NULL) 
			return m_pUnknownOuter->AddRef() ;  
	//	else 
	//		return NondelegatingAddRef(); 
	} 
 
	virtual ULONG __stdcall Release()  
	{ 
		trace("代理接口 Release.") ; 
	//	if (m_pUnknownOuter != NULL) 
			return m_pUnknownOuter->Release() ;  
	//	else 
	//		return NondelegatingRelease(); 
	} 
 
	// Nondelegating IUnknown 
	virtual HRESULT __stdcall 
		NondelegatingQueryInterface(const IID& iid, void** ppv) ; 
	virtual ULONG   __stdcall NondelegatingAddRef() ; 
	virtual ULONG   __stdcall NondelegatingRelease() ; 
 
	// Interface IY 
	virtual void __stdcall Fy() { cout << "Fy" << endl ;} 
 
	// Constructor 
	CB(IUnknown* m_pUnknownOuter) ; 
 
	// Destructor 
	~CB() ; 
 
private: 
	long m_cRef ; 
	 
	IUnknown* m_pUnknownOuter ; 
} ; 
 
// 
// IUnknown implementation 
// 
HRESULT __stdcall CB::NondelegatingQueryInterface(const IID& iid, 
                                                  void** ppv) 
{ 	 
	if (iid == IID_IUnknown) 
	{ 
		// !!! CAST IS VERY IMPORTANT !!! 
		trace("非代理IUnknown接口返回INondelegatingUnknown接口指针!"); 
		*ppv = static_cast(this) ;  // @N 
	} 
	else if (iid == IID_IY) 
	{ 
		trace("非代理IUnknown接口返回IY接口指针!"); 
		if (m_pUnknownOuter != NULL) 
		   trace("m_pUnknownOuter!=NULL.") ; 
		*ppv = static_cast(this) ; 
	} 
	else 
	{ 
		*ppv = NULL ; 
		return E_NOINTERFACE ; 
	} 
	reinterpret_cast(*ppv)->AddRef() ; 
	return S_OK ; 
} 
 
ULONG __stdcall CB::NondelegatingAddRef() 
{ 
	return ::InterlockedIncrement(&m_cRef) ; 
} 
 
ULONG __stdcall CB::NondelegatingRelease()  
{ 
	if (::InterlockedDecrement(&m_cRef) == 0) 
	{ 
		delete this ; 
		return 0 ; 
	} 
	return m_cRef ; 
} 
 
// 
// Constructor 
// 
CB::CB(IUnknown* pUnknownOuter)  
: m_cRef(1) 
{  
	::InterlockedIncrement(&g_cComponents) ;  
 
	if (pUnknownOuter == NULL) 
	{ 
		trace("未被聚合,m_pUnKnownOuter指向内部组件的非代理接口") ; 
		m_pUnknownOuter = reinterpret_cast 
		                  (static_cast 
		                  (this)) ; 
	} 
	else 
	{ 
		trace("聚合,m_pUnKnownOuter指向外部组件的IUNKNOWN接口") ; 
		m_pUnknownOuter = pUnknownOuter ; 
	} 
} 
 
// 
// Destructor 
// 
CB::~CB()  
{  
	::InterlockedDecrement(&g_cComponents) ;  
	trace("Destroy self.") ; 
} 
 
/////////////////////////////////////////////////////////// 
// 
// Class factory 
// 
class CFactory : public IClassFactory 
{ 
public: 
	// IUnknown 
	virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ; 
	virtual ULONG   __stdcall AddRef() ; 
	virtual ULONG   __stdcall Release() ; 
 
	// Interface IClassFactory 
	virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter, 
	                                         const IID& iid, 
	                                         void** ppv) ; 
	virtual HRESULT __stdcall LockServer(BOOL bLock) ;  
 
	// Constructor 
	CFactory() : m_cRef(1) {} 
 
	// Destructor 
	~CFactory() {} 
	 
private: 
	long m_cRef ; 
} ; 
 
// 
// Class factory IUnknown implementation 
// 
HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv) 
{ 	 
	if ((iid == IID_IUnknown) || (iid == IID_IClassFactory)) 
	{ 
		*ppv = static_cast(this) ;  
	} 
	else 
	{ 
		*ppv = NULL ; 
		return E_NOINTERFACE ; 
	} 
	reinterpret_cast(*ppv)->AddRef() ; 
	return S_OK ; 
} 
 
ULONG __stdcall CFactory::AddRef() 
{ 
	return ::InterlockedIncrement(&m_cRef) ; 
} 
 
ULONG __stdcall CFactory::Release()  
{ 
	if (::InterlockedDecrement(&m_cRef) == 0) 
	{ 
		delete this ; 
		return 0 ; 
	} 
	return m_cRef ; 
} 
 
// 
// IClassFactory implementation 
// 
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter, 
	                                   const IID& iid, 
	                                   void** ppv) 
{ 
	// Aggregate only if the requested iid is IID_IUnknown. 
	if ((pUnknownOuter != NULL) && (iid != IID_IUnknown)) //@N 
	{ 
		return CLASS_E_NOAGGREGATION ; 
	} 
	 
	// Create component. 
	CB* pB = new CB(pUnknownOuter) ; // @N 
	if (pB == NULL) 
	{ 
		return E_OUTOFMEMORY ; 
	} 
	 
	// Get the requested interface. 
	HRESULT hr = pB->NondelegatingQueryInterface(iid, ppv) ; //@N 
	pB->NondelegatingRelease() ;  
	return hr ;    
} 
 
// LockServer 
HRESULT __stdcall CFactory::LockServer(BOOL bLock)  
{ 
	if (bLock)  
	{ 
		::InterlockedIncrement(&g_cServerLocks) ;  
	} 
	else 
	{ 
		::InterlockedDecrement(&g_cServerLocks) ; 
	} 
	return S_OK ; 
} 
 
 
/////////////////////////////////////////////////////////// 
// 
// Exported functions 
// 
 
STDAPI DllCanUnloadNow() 
{ 
	if ((g_cComponents == 0) && (g_cServerLocks == 0)) 
	{ 
		return S_OK ; 
	} 
	else 
	{ 
		return S_FALSE ; 
	} 
} 
 
// 
// Get class factory. 
// 
STDAPI DllGetClassObject(const CLSID& clsid, 
                         const IID& iid, 
                         void** ppv)  
{ 
	// Can we create this component? 
	if (clsid != CLSID_Component2) 
	{ 
		return CLASS_E_CLASSNOTAVAILABLE ; 
	} 
 
	// Create class factory. 
	CFactory* pFactory = new CFactory ; // No Addref in constructor 
	if (pFactory == NULL) 
	{ 
		return E_OUTOFMEMORY ; 
	} 
 
	// Get requested interface. 
	HRESULT hr = pFactory->QueryInterface(iid, ppv) ; 
	pFactory->Release() ; 
 
	return hr ;	    
} 
 
// 
// Server registration 
// 
STDAPI DllRegisterServer() 
{ 
	return RegisterServer(g_hModule, 
	                      CLSID_Component2,  
	                      g_szFriendlyName, 
	                      g_szVerIndProgID, 
	                      g_szProgID) ; 
} 
 
 
STDAPI DllUnregisterServer() 
{ 
	return UnregisterServer(CLSID_Component2, 
	                        g_szVerIndProgID, 
	                        g_szProgID) ; 
} 
 
/////////////////////////////////////////////////////////// 
// 
// DLL module information 
// 
BOOL APIENTRY DllMain(HANDLE hModule, 
                      DWORD dwReason, 
                      void* lpReserved) 
{ 
	if (dwReason == DLL_PROCESS_ATTACH) 
	{ 
		g_hModule = (HMODULE)hModule ; 
	} 
	return TRUE ; 
}