www.pudn.com > Ge_opc_Server_v1.rar > OPCFACT.CPP


// OpcFact.cpp 
// 
//   This file contains the implementation of the OPCClassFactory 
//   for the OPC server. 
// 
// Note: the combination of 'ServerDestroyed' and 'OPCServerUnload' 
//   Allow this class factory to work with both EXE and DLL versions. 
//   There are many ways to provide this functionality and all of them 
//	 are a bit convoluted. This is modeled on BrockSchmidt 2nd edition. 
//	 See Chap 5, 'The Class Factory and the Unloading Mechanism' 
//	 See also DLLMAIN.CPP and EXEMAIN.CPP 
// 
// 
//	(c) COPYRIGHT 1996, INTELLUTION INC. 
// ALL RIGHTS RESERVED 
// 
// Original Author: Al Chisholm 
// 
// Modification Log: 
//	Vers    Date   By    Notes 
//	----  -------- ---   ----- 
//	0.00  11/18/96 ACC 
// 
// 
 
#define WIN32_LEAN_AND_MEAN 
 
#include "OPCLHEpipeview.h" 
#include "OPCFact.h" 
 
void ServerDestroyed(void); 
 
 
 
 
/////////////////////////////////////// 
// OPCClassFactory() 
//   Constructor for the OPC class factory. 
/////////////////////////////////////// 
OPCClassFactory::OPCClassFactory(REFCLSID rid) 
{ 
	mRefCount = 0; 
} 
 
 
 
 
/////////////////////////////////////// 
// QueryInterface() 
//   Implementation of the standard IUnknown QueryInterface() 
//   for the OPC class factory. 
/////////////////////////////////////// 
STDMETHODIMP OPCClassFactory::QueryInterface( REFIID iid, LPVOID* ppInterface) 
{ 
	if ( ppInterface == NULL) 
		return E_INVALIDARG; 
 
	if ( iid == IID_IUnknown || iid == IID_IClassFactory) 
	{ 
		*ppInterface = this; 
		AddRef(); 
		return S_OK; 
	} 
 
	*ppInterface = NULL; 
	return E_NOINTERFACE; 
} 
 
 
 
/////////////////////////////////////// 
// AddRef() 
//   Implementation of the standard IUnknown AddRef() 
//   for the OPC class factory. 
/////////////////////////////////////// 
STDMETHODIMP_(ULONG) OPCClassFactory::AddRef( void) 
{ 
	return ++mRefCount; 
} 
 
 
 
/////////////////////////////////////// 
// Release() 
//   Implementation of the standard IUnknown Release() 
//   for the OPC class factory. 
/////////////////////////////////////// 
STDMETHODIMP_(ULONG) OPCClassFactory::Release( void) 
{ 
	ULONG currentCount = --mRefCount; 
	if ( currentCount == 0) 
		delete this; 
	return currentCount; 
} 
 
 
 
/////////////////////////////////////// 
// CreateInstance() 
//   This function creates an instance of the OPC server. 
/////////////////////////////////////// 
STDMETHODIMP OPCClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppvObject) 
{ 
	if ( pUnkOuter != NULL) 
		return CLASS_E_NOAGGREGATION;	// Aggregation is not supported by this code 
 
	// Create a new server instance 
	// We keep a count of the number created by the calling ap. 
	// If that number goes to 0  (when the last interface 
	//  is released and the last server is destroyed) 
	//  then the DLL or EXE can be unloaded. 
	// 
	LHEpipeviewServer* pServer = new LHEpipeviewServer(pUnkOuter, ServerDestroyed); 
	if ( pServer == NULL) 
	{ 
		OPCServerUnload(); // used only for EXE version... 
		return E_OUTOFMEMORY; 
	} 
 
	HRESULT hr = pServer->QueryInterface( riid, ppvObject); 
	if ( FAILED( hr)) 
	{ 
		delete pServer; 
		OPCServerUnload(); // used only for EXE version... 
	} 
	else 
	{ 
		objectCount++; 
	} 
 
	return hr; 
} 
 
 
/////////////////////////////////////// 
// Called by server objects when they are destroyed 
//  so that we can tell if there are any left 
//  for the DLL or EXE to manage. 
//  See DLLCanUnloadNow for DLLs or OPCServerUnload for EXEs 
// 
/////////////////////////////////////// 
void ServerDestroyed(void) 
{ 
		objectCount--; 
		OPCServerUnload(); // used only for EXE version... 
} 
 
/////////////////////////////////////// 
// LockServer() 
//   This is a standard implementation of the IClassFactory::LockServer() function that either 
//   adds or removes a lock on the server. 
// 
/////////////////////////////////////// 
STDMETHODIMP OPCClassFactory::LockServer( BOOL fLock) 
{ 
	if ( fLock) 
		lockCount++; 
	else 
		lockCount--; 
 
	return S_OK; 
}