?? impiclassfactory.cpp
字號:
// ImpIClassFactory.cpp
//
// This file contains the implementation of the OPCClassFactory
// for the OPC sample 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-1998, INTELLUTION INC.
// ALL RIGHTS RESERVED
//
//
// Functions defined in this module:
//
// CImpIClassFactory::CImpIClassFactory()
// CImpIClassFactory::~CImpIClassFactory()
// CImpIClassFactory::AddRef()
// CImpIClassFactory::Release()
// CImpIClassFactory::QueryInterface()
// CImpIClassFactory::CreateInstance()
// CImpIClassFactory::LockServer()
// CImpIClassFactory::ServerDestroyed()
//
//
//
// Modification Log:
// Vers Date By Notes
// ---- -------- --- -----
// 1.1 08/26/97 jra Created
// 1.3 03/10/98 jra Modified to be wizard generated and driver specific.
// 7.11 02/23/99 jra Modified CreateInstance() to save the return from QueryInterface()
//
//
#define WIN32_LEAN_AND_MEAN
#include "OpcStdAfx.h"
#include "OPCDrv.h"
void ServerDestroyed(void);
extern long g_lObjectCount;
extern long g_lLockCount;
extern BOOL ServerCanUnloadNow(void);
////////////////////////////////////////////////////////////////
// OPCClassFactory()
//
// Constructor for the OPC class factory.
//
////////////////////////////////////////////////////////////////
CImpIClassFactory::CImpIClassFactory(REFCLSID rid)
{
m_lRefCount = 0;
}
////////////////////////////////////////////////////////////////
// QueryInterface()
//
// Implementation of the standard IUnknown QueryInterface()
// for the OPC class factory.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIClassFactory::QueryInterface(REFIID riid, LPVOID* ppv)
{
if (ppv == NULL)
{
return E_INVALIDARG;
}
*ppv = NULL;
if (riid == IID_IUnknown)
{
*ppv = (IUnknown *)this;
}
else if (riid == IID_IClassFactory)
{
*ppv = (IClassFactory *)this;
}
else
{
return E_NOINTERFACE;
}
((IUnknown *)*ppv)->AddRef();
return S_OK;
}
////////////////////////////////////////////////////////////////
// AddRef()
//
// Implementation of the standard IUnknown AddRef() for the
// OPC class factory.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CImpIClassFactory::AddRef(void)
{
return InterlockedIncrement(&m_lRefCount);
}
////////////////////////////////////////////////////////////////
// Release()
//
// Implementation of the standard IUnknown Release()
// for the OPC class factory.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CImpIClassFactory::Release(void)
{
ULONG currentCount = InterlockedDecrement(&m_lRefCount);
if (0 == currentCount)
{
delete this;
}
return currentCount;
}
////////////////////////////////////////////////////////////////
// CreateInstance()
//
// This function creates an instance of the OPCDrv Server.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID *ppvObject)
{
HRESULT hr;
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.
//
COPCDrvServer *pServer = new COPCDrvServer(pUnkOuter, ServerDestroyed);
if (NULL == pServer)
{
return E_OUTOFMEMORY;
}
if (FAILED(hr = pServer->Init()))
{
delete pServer;
return E_UNEXPECTED;
}
// jra 022399
// Save the return from QueryInterface()
if (FAILED(hr = pServer->QueryInterface(riid, ppvObject)))
{
delete pServer;
}
else
{
InterlockedIncrement(&g_lObjectCount);
}
return hr;
}
////////////////////////////////////////////////////////////////
// LockServer()
//
// This is a standard implementation of the IClassFactory::LockServer()
// function that either adds or removes a lock on the server.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIClassFactory::LockServer(BOOL bLock)
{
if (bLock)
{
InterlockedIncrement(&g_lLockCount);
}
else
{
InterlockedDecrement(&g_lLockCount);
if (ServerCanUnloadNow())
{
OPCServerUnload();
}
}
return S_OK;
}
////////////////////////////////////////////////////////////////
// ServerDestroyed()
//
// 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)
{
InterlockedDecrement(&g_lObjectCount);
OPCServerUnload();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -