Иллюстрированный самоучитель по Visual Studio .NET

Создание класса СОМ-объекта

Подключите к проекту новый файл MyCom.h, в который надо поместить объявление класса CoSay. Как вы помните, он должен быть потомком экспортируемого интерфейса iSay и дать тела всем методам, унаследованным от всех своих абстрактных предков (isay, lUnknown). Введите в файл следующие коды:

# if!defined (MY_COSAY_HEADER)
#define MY_COSAY_HEADER
#pragma once
class CoSay: public ISay
{
//=====Класс, реализующий интерфейсы ISay, lUnknown
public:
CoSay ();
virtual – CoSay();
// lUnknown
HRESULT _ stdcall Querylnterface(REFIID riid, void** ppv);
ULONG _ stdcall AddRefO;
ULONG _ stdcall Release ();
// ISay
HRESULT _ stdcall Say();
HRESULT _ stdcall SetWord (BSTR word);
private:
//====== Счетчик числа пользователей классом
ULONG m_ref;, //====== Текст, выводимый в окно
BSTR m word;
};
# endif

Для реализации тел методов класса CoSay подключите к проекту новый файл МуСоm.срр, в который введите коды, приведенные ниже. Обратите внимание на то, как принято работать со строками текста типа BSTR:

#include "interfaces.h"
#include "MyCom.h"
//====== Произвольный ограничитель длины строк
#define MAX_LENGTH 128
CoSay::CoSay()
{
//=== Обнуляем счетчик числа пользователей класса,
//=== так как интерфейс пока не используется
m_ref = 0;
//=== Динамически создаем строку текста по умолчанию
m_word = SysAllocString (L"Hi, there."
"This is MyCom speaking");
}
CoSay::-CoSay()
{
//=== При завершении работы освобождаем память
if (m_word)
SysFreeString(m_word);
}
//====== Реализация методов lUnknown
HRESULT _ stdcall CoSay::QueryInterface(REFIID riid, void** ppv)
{
//====== Стандартная логика работы с клиентом
//====== Поддерживаем только два интерфейса
*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;
}
ULONG _ stdcall CoSay:-.AddRef ()
{
return ++m_ref;
}
ULONG _ stdcall CoSay::Release()
{
if (--m_ref==0) delete this;
return m_re f;
}
//====== Реализация методов ISay
HRESULT _ stdcall 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;
}
HRESULT _ stdcall CoSay::SetWord(BSTR word)
{
//====== Повторное выделение памяти
SysReAllocString (&m_word, word);
freturn S_OK;
}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.