4. Переведите фокус в поле Initial Directory и с помощью кнопки раскрытия выпадающего списка выберите элемент Item Directory и нажмите OK
С помощью команды Create GUID меню Tools вызовите генератор уникальных идентификаторов. Выберите формат DEFINE_GUID, нажмите кнопку Copy, а затем Exit.
В окне редактора студии (с файлом guids.h) поместите фокус перед строкой interface ISay и нажмите Ctrl+V. При этом из системного буфера в файл будут помещены три строки кода, которые с точностью до цифр (у вас они будут другими) имеют такой вид:
// {170368D0-85BE-43af-AE71-053F506657A2}
DEFINE_GUID(<<name>>,
0x170368d0, 0x85be, 0x43af, 0xae, 0x71, 0x5, 0x3f, 0x50,
0x66, 0x57, 0xa2);
Замените аргумент <<name>> (вместе с угловыми скобками) на IID_ISay. Повторите всю процедуру и создайте идентификатор для ко-класса CoSay, который вставьте сразу за идентификатором интерфейса ISay. На сей раз замените аргумент <<name>> на CLSID_CoSay, как показано ниже:
// {9B865820-2FFA-11d5-98B4-00E0293F01B2}
DEFINE_GUID(CLSID_CoSay,
0x9b865820, 0x2ffa, 0x11d5, 0x98, 0xb4, 0x0, 0xe0, 0x29,
0x3f, 0x1, 0xb2);
Сохраните и закройте файл guids.h, так как мы больше не будем вносить в него изменений. Если вы хотите знать, что делает макроподстановка DEFINE_GUID, то за ней стоит такое определение:
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
Этот макрос создает структуру типа GUID с именем name, которая служит для хранения уникальных идентификаторов COM-объектов, интерфейсов, библиотек типов и других "бирочных" реалий причудливого мира COM.
Интерфейс определен, теперь надо создать ко-класс, который реализует (implements) его методы и предоставит (expose) его миру. Подключите к проекту новый файл MyCom.h, в который надо поместить объявление класса CoSay. Как вы помните, он должен быть потомком экспортируемого интерфейса ISay и дать тела всем методам, унаследованным от всех своих абстрактных предков (ISay, IUnknown). Введите в файл следующие коды:
#pragma once
class CoSay : public ISay // Класс, реализующий интерфейсы ISay, IUnknown
{
private:
ULONG m_ref; // Счетчик числа пользователей классом
BSTR m_word; // Текст, выводимый в окно
public:
CoSay();
virtual ~CoSay();
// Реализация обещаний деда - IUnknown
HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
ULONG __stdcall AddRef();
ULONG __stdcall Release();
// Реализация обещаний родителя - ISay
HRESULT __stdcall Say();
HRESULT __stdcall SetWord (BSTR word);
};
Для реализации тел методов класса CoSay подключите к проекту новый файл MyCom.cpp, в который введите коды, приведенные ниже. Обратите внимание на то, как принято работать со строками текста типа BSTR.
#include "guids.h"
#include "MyCom.h"
CoSay::CoSay()
{
m_ref = 0; // Обнуляем счетчик числа пользователей класса (интерфейс пока не используется)
// Динамически создаем строку текста (по умолчанию)
m_word = SysAllocString (L"Hi, there. This is MyCom speaking");
}
CoSay::~CoSay()
{
if (m_word) // При завершении работы освобождаем память
SysFreeString (m_word);
}
//==== Реализация методов IUnknown
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_ref;
}
HRESULT __stdcall CoSay::Say() // Реализация методов ISay
{
char buff [128]; // Преобразование типов (из BSTR в char*) необходимо для MessageBox
WideCharToMultiByte (CP_ACP, 0, m_word, -1, buff, MAX_LENGTH, 0, 0);
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.