// ClassFactory.h - Copyright (C) 2000 Pat Thoyts // // Template class for COM ClassFactory objects. // // @(#)$Id: ClassFactory.h,v 1.1.1.1 2000/11/20 02:10:46 pat Exp $ #ifndef _H_CLASSFACTORY #define _H_CLASSFACTORY #if _MSC_VER > 1000 #pragma once #endif #include #include #ifdef _MSC_VER #pragma warning(disable:4800) // disable BOOL to bool warnings #endif // _MSC_VER template class CClassFactory : public IClassFactory { public: STDMETHOD(QueryInterface)(REFIID riid, void** ppv); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)(); STDMETHOD(CreateInstance)(IUnknown* pUnknownOuter, REFIID riid, void** ppv); STDMETHOD(LockServer)(BOOL fLock); bool CanUnloadNow(); void DecrementObjectCount(); private: long m_lRefCount; long m_lObjectCount; long m_lLockCount; }; // Implementation ------------------------------------------------------- template STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void** ppv) { HRESULT hr = S_OK; *ppv = 0; if (riid == IID_IUnknown || riid == IID_IClassFactory) *ppv = static_cast(this); else hr = E_NOINTERFACE; static_cast(*ppv)->AddRef(); return hr; } template STDMETHODIMP_(ULONG) CClassFactory::AddRef() { return InterlockedIncrement(&m_lRefCount); } template STDMETHODIMP_(ULONG) CClassFactory::Release() { if (InterlockedDecrement(&m_lRefCount) == 0) { // We don't delete this object, CanUnloadNow will indicate // that the library can be unloaded which will handle that. return 0; } return m_lRefCount; } template STDMETHODIMP CClassFactory::CreateInstance(IUnknown * pUnknownOuter, REFIID riid, void** ppv) { *ppv = 0; if (pUnknownOuter != 0) // don't aggregate return CLASS_E_NOAGGREGATION; T* pCoClass = new T; if (pCoClass == 0) return E_OUTOFMEMORY; HRESULT hr = pCoClass->QueryInterface(riid, ppv); if (FAILED(hr)) { delete pCoClass; return hr; } InterlockedIncrement(&m_lObjectCount); return S_OK; } template STDMETHODIMP CClassFactory::LockServer(BOOL fLock) { if (fLock) InterlockedIncrement(&m_lLockCount); else InterlockedDecrement(&m_lLockCount); return S_OK; } template bool CClassFactory::CanUnloadNow() { if (m_lLockCount != 0) return false; if (m_lObjectCount != 0) return false; if (m_lRefCount != 0) return false; return true; } template void CClassFactory::DecrementObjectCount() { if (m_lObjectCount > 0) InterlockedDecrement(&m_lObjectCount); } #endif /* _H_CLASSFACTORY */ // Local variables: // mode: c++ // indent-tabs-mode: nil // c-file-style: "stroustrup" // End: