Использование макросов COM
// Поддерживаем только два интерфейса
//====== Реализация lUnknown *ppv = 0;
if (riid==IID_IUnknown)
*ppv = static_cast<IUnknown*>(this);
else if (riid==IID_ISay)
*ppv = static_cast<ISay*>(this);
else
return E_NOINTERFACE;
//====== Добавляем единицу к счетчику
//====== пользователей нашим объектом
AddRef ();
return S_OK;
}
STDMETHODIMP_(ULONG) CoSay::AddRef()
{
return ++m_ref;
}
STDMETHODIMP_(ULONG) CoSay::Release ()
{
if (--m_ref==0)
delete this;
return m_ref;
}
//====== Реализация ISay
STDMETHODIMP CoSay::Say()
{
//=== Преобразование типов (из BSTR в char*),
//=== которое необходимо для использования
MessageBox char buff[MAX_LENGTH];
WideCharToMultiByte(CP_ACP, 0, m_word, – 1,
buff, MAX_LENGTH, 0, 0);
MessageBox (0, buff, "Interface ISay:", MB_OK);
return S_OK;
}
STDMETHODIMP CoSay::SetWord(BSTR word)
{
//====== Повторное зыделение памяти
SysReAllocString(&m_word, word);
return S_OK;
}
STDAPI DllGetClassObject (REFCLSID rclsid,
REFIID riid, LPVOID* ppv)
{
if (rclsid!= CLSID_CoSay)
return CLASS_E_CLASSNOTAVAILABLE;
CoSayFactory *pCF = new CoSayFactory;
HRESULT hr = pCF › Query!nterface(riid, ppv);
if (FAILED(hr)) delete pCF;
return hr;
}
STDAPI DllCanUnloadNow()
{
//====== Если счетчики нулевые, то мы позволяем
//====== системе выгрузку DLL-сервера
return IgLockCount && IgObjCount? S_OK: S_FALSE;
}
//====== Фабрика классов
CoSayFactory::CoSayFactory()
{
m_ref = 0;
gObjCount++;
}
CoSayFactory::-CoSayFactory()
gObjCount--;
}
//====== Методы lUnknown
STDMETHODIMP CoSayFactory
::QueryInterface(REFIID riid, void** ppv)
{
*ppv = 0;
//=== Обходимся без шаблона static casto
if (riid == IID_IUnknown)
*ppv = (lUnknown*) this;
else if (riid == IID_IClassFactory)
*ppv = (IClassFactory*)this;
else
return E_NOINTERFACE;
AddRef ();
return S_OK;
}