Модель программирования Component Object Model. Разработка COM-сервера, страница 19

1.  Дайте команду Add4Add Class и просмотрите допустимые категории объектов, вкладываемых в COM DLL (COM-объектами называются ко-классы, которые реализуют интерфейс IClassFactory);

2.  В окне Templates выберите тип объекта ATL Simple Object и нажмите кнопку Open;

3.  В окне следующего мастера (ATL Simple Object Wizard) задаются атрибуты ко-класса, а на вкладке Options — его первого интерфейса;

4.  Введите имя (Short Name) класса Say и убедитесь, что автоматически генерируется имя первого интерфейса класса. Оно должно быть ISay;

5.  Перейдите на другую страницу (Options) мастера и установите переключатели: Interface в положение Custom, Threading Model в Single, Aggregation в No и нажмите OK.

Просмотрите дерево классов. Там появились два новых элемента: класс CSay и интерфейс ISay. Раскройте узел дерева с именем CSay и вы увидите, что внутри него есть узел с именем Bases and Interfaces. Раскройте его и найдите еще один узел с именем ISay. На самом деле эти узлы приводят вас к одному и тому же IDL-файлу с декларацией интерфейса ISay. Обратите внимание на то, что IDL-файл пополнился описанием интерфейса и ко-класса, который вставлен внутрь блока с описанием библиотеки типов сервера (library ATestLib).

import "oaidl.idl";

import "ocidl.idl";

[

object,

uuid(A1B87395-F307-476A-8BD9-00EC7801F320),

helpstring("ISay Interface"),

pointer_default(unique)

]

interface ISay : IUnknown{};

[

uuid(EFBDB9DA-347D-4CE5-A13D-CF2CEF3684F1),

version(1.0),

helpstring("ATest 1.0 Type Library")

]

library ATestLib

{

importlib("stdole2.tlb");

[

uuid(A11284B1-5B4E-4702-9716-18C2B4063D55),

helpstring("Say Class")

]

coclass Say

{

[default] interface ISay;

};

};

Откройте также в окне редактора файл сценария регистрации (Say.rgs). Он в интуитивно-ясной форме описывает что будет внесено в Windows-реестр при автоматической регистрации сервера при его запуске. Наш сервер является саморегистрируемым, так как в состав экспортируемых им функций входит DllRegisterServer.

HKCR

{

ATest.Say.1 = s 'Say Class'

{

CLSID = s '{A11284B1-5B4E-4702-9716-18C2B4063D55}'

}

ATest.Say = s 'Say Class'

{

CLSID = s '{A11284B1-5B4E-4702-9716-18C2B4063D55}'

CurVer = s 'ATest.Say.1'

}

NoRemove CLSID

{

ForceRemove {A11284B1-5B4E-4702-9716-18C2B4063D55} = s 'Say Class'

{

ProgID = s 'ATest.Say.1'

VersionIndependentProgID = s 'ATest.Say'

InprocServer32 = s '%MODULE%'

{

}

val AppID = s '%APPID%'

'TypeLib' = s '{EFBDB9DA-347D-4CE5-A13D-CF2CEF3684F1}'

}

}

}

Здесь HKCR означает улей HKEY_CLASSES_ROOT. Каждый блок означает вложенный элемент дерева. Например, первый вложенный блок означает, что после регистрации в реестре появится ключ (key) ATest.Say.1, значением (value) которого будет строка 'Say Class'. У этого узла будет подключ

CLSID = s '{A11284B1-5B4E-4702-9716-18C2B4063D55}'

со строковым значением {A11284B1-5B4E-4702-9716-18C2B4063D55}. Модификатор ForceRemove означает, что если ключ существует, то он и все его подключи будут удалены и вместо них появится ключ, описание которого следует за модификатором. Модификатор NoRemove указывает на то, что все подключи данного ключа останутся нетронутыми. Модификатор Delete, который здесь не используется, но в принципе существует, указывает на необходимость удаления ключа и всех его подключей.

Для того, чтобы убрать все записи из реестра можно воспользоваться утилитой regsvr32, которая лежит в WinNT\System32. Она обратится к функции DllUnregisterServer, которая экспортируется нашим сервером, и она произведет очистку реестра. Для этого вы должны запустить утилиту из командной строки с ключом –u (что означает unregister) и параметром, который является адресом нашей DLL. Например: regsvr32 -u "D:\ATest\Debug\ATest.dll". Если файловый адрес содержит пробелы, то его следует заключить в кавычки.

Наконец, рассмотрите внимательно сам класс CSay, декларация которого размещена в файле Say.h. Вы увидите, что он произведен от трех родителей: CComObjectRootEx, CComCoClass, и ISay. Присутсвие последнего родителя вам должно быть понятно, так как именно его методы должен экспонировать класс CSay.