Imagine you ATL code had something like this:
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_Obj1, CObj1)
OBJECT_ENTRY(CLSID_Obj2, CObj2)
OBJECT_ENTRY(CLSID_Obj3, CObj3)
END_OBJECT_MAP()
In your class factory, you need to be able to create the correct object. First I fixed my class factory object.
I added a new member variable:
REFCLSID m_clsid;
And got is set in the constructor:
CClassFactory::CClassFactory(
REFCLSID clsid) : m_cRef(1), m_clsid(clsid)
{
IncModuleCount();
} // CClassFactory::CClassFactory
Next I fixed my CreateInstance method
STDMETHODIMP CClassFactory::CreateInstance(
__in_opt IUnknown *pUnkownOuter,
REFIID riid,
__deref_out_opt void **ppv)
{
HRESULT hr = S_OK;
IUnknown *pUnknown = NULL;
if (ppv)
{
*ppv = NULL;
}
else
{
hr = E_INVALIDARG;
}
if (S_OK == hr)
{
if (pUnkownOuter)
{
hr = CLASS_E_NOAGGREGATION;
}
}
if (S_OK == hr)
{
if (CLSID_Obj1 == m_clsid)
{
pUnknown = new CObj1();
}
else if (CLSID_Obj2 == m_clsid)
{
pUnknown = new CObj2();
}
else if (CLSID_Obj3 == m_clsid)
{
pUnknown = new CObj3();
}
else
{
hr = E_NOINTERFACE;
}
if (S_OK == hr && !pUnknown)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
hr = pUnknown->QueryInterface(riid, ppv);
}
if (pUnknown)
{
pUnknown->Release();
}
return hr;
} // CClassFactory::CreateInstance
And then fixed my DllGetClassObject
STDAPI DllGetClassObject(
__in REFCLSID rclsid,
__in REFIID riid,
__deref_out LPVOID FAR *ppv)
{
HRESULT hr = S_OK;
CClassFactory *pClassFactory = NULL;
if (ppv)
{
*ppv = NULL;
}
else
{
hr = E_INVALIDARG;
}
if (S_OK == hr)
{
pClassFactory = new CClassFactory(rclsid);
if (!pClassFactory)
{
hr = E_OUTOFMEMORY;
}
}
if (S_OK == hr)
{
hr = pClassFactory->QueryInterface(riid, ppv);
}
if (pClassFactory)
{
pClassFactory->Release();
}
return hr;
}
No comments:
Post a Comment