Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Создание отчето... 65101
Модуль Forms 64873
Пример работы с... 63336
ТЕХНОЛОГИИ ДОСТ... 61573
Имитационное мо... 57436
Реклама
Сейчас на сайте
Гостей: 11
На сайте нет зарегистрированных пользователей

Пользователей: 13,081
новичок: Abdukarimov A
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

База данных междугородних телефонных разговоров на Delphi
База данных студентов на Delphi + Microsoft SQL Server
Двунаправленный динамический список на Delphi + Блок схемы

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Категории компонентов



Как подчеркивалось в этой главе, основные примитивы активации СОМ требуют, чтобы вызывающей программе при создании новых экземпляров класса было известно его точное имя. Иногда, однако, бывает полезно просто потребовать, чтобы подходящим являлся любой класс, удовлетворяющий некоторым семантическим ограничениям. Кроме того, прежде чем сделать запрос на активацию, было бы полезно знать, какие сервисные средства класс требует от своих клиентов. В этом случае не будут создаваться объекты, которые клиент не готов должным образом поддерживать. Эти проблемы послужили причиной для создания категорий компонентов ( component categories ).
СОМ дает разработчикам возможность группировать родственные СОМ-классы в логические группы, или категории компонентов. Чаще всего все классы внутри категории будут реализовывать один и тот же набор интерфейсов. В то же время простое разделение пространства классов на части по признаку, какие интерфейсы какой класс реализует, не обеспечивает должного уровня модульности для многих приложений. Категории компонентов выступают как метаинформация, показывающая, какие классы совместимы с определенными семантическими ограничениями.
Категория компонентов есть группа логически родственных СОМ-классов, которые разделяют общий ID категории, или CATID . Идентификаторы категории CATID – это GUID, записанные в реестре как атрибуты класса. Каждый класс может иметь два подключа: Implemented Categories и Required Categories (реализованные категории и нужные категории). Представим, что есть две категории компонентов: Simians и Mammals (приматы и млекопитающие). Каждая из этих двух категорий будет иметь уникальный CATID ( CATID_Simians и CATID_Mammals соответственно). Допустим, что класс Chimp является членом каждой из этих категорий, и тогда для Chimp ключ реестра Implemented Categories будет содержать в себе каждый GUID как отдельный подключ:
[HKCR\CLSID\{CLSID_Chimp}\Implemented Categories\{CATID_Mammals}]
[HKCR\CLSID\{CLSID_Chimp}\Implemented Categories\{CATID_Simians}]

Эти элементы реестра обычно добавляются во время саморегистрации. Каждая известная категория компонентов в системе имеет запись в разделе реестра HKEY_CLASSES_ROOT\Component Categories
Каждая категория имеет свой собственный уникальный подключ, названный как CATID . Под этим подключом каждая категория имеет одну или более именованных величин, содержащих текстовое описание этой категории. Например, двум показанным выше категориям понадобятся такие элементы реестра:
[HKCR\Component Categories\{CATID_Mammals}] 409="Bears live young"
[HKCR\Component Categones\{CATID_Simians}] 409="Eats Bananas"

Отметим, что в этом примере используется величина 409, являющаяся кодом локализации, или локальным идентификатором языка LCID (locale identifier), для U.S.English. Другая местная специфика может поддерживаться путем добавления дополнительных именованных величин.
Классы также могут указать, что они требуют от клиента функциональное назначение определенного типа. Обычно такая поддержка принимает вид узловых интерфейсов ( site interfaces ), которые клиент предоставляет активированному объекту. Для того, чтобы разделить эти предоставляемые клиентом сервисы на категории, не зависящие от отдельного интерфейса, СОМ позволяет классам объявлять второй тип категорий ID; он может использоваться клиентами для гарантии того, что они не активировали компонент, который не могут должным образом принять. Рассмотрим следующие две категории сервисов, предоставляемых клиентом: CATID_HasOxygen и CATID_HasWater . Поскольку для выживания шимпанзе необходимы кислород и вода, разработчик Chimp должен объявить, что эти две категории сервисов, предоставляемых клиентом, необходимы для активации. Это делается с помощью подключей из Required Categories :
[HKCR\CLSID\{CLSID_Chimp}\Required Categories\{CATID_HasOxygen}]
[HKCR\CLSID\{CLSID_Chimp}\Required Categories\{CATID_HasWater}]

Кроме того, ID этих двух категорий следует внести в реестр под ключом HKEY_CLASSES_ROOT\Component Categories
Получив эти записи, сам клиент перед активацией должен убедиться в том, что он удовлетворяет запрошенным категориям. СОМ не обеспечивает согласование с клиентом.
Элементы категорий компонентов могут быть зарегистрированы либо с помощью явных функций реестра, либо с использованием предлагаемого СОМ менеджера категорий компонентов ( component category manager ). Этот менеджер категорий компонентов объявляется в СОМ как создаваемый СОМ-класс ( CLSID_StdComponentCategoriesMgr ), который реализует интерфейс ICatRegister для регистрации информации о категории и интерфейс ICatInformation для запроса информации о категории. Интерфейс ICatRegister позволяет библиотекам DLL сервера легко добавлять в реестр необходимые элементы:
[object, uuid(0002E012-0000-0000-C000-000000000046)]
interface ICatRegister : IUnknown {
// description info for a category
// описательная информация для категории
typedef struct tagCATEGORYINFO
{ CATID catid; LCID lcid; OLECHAR szDescription[128]; }
CATEGORYINFO;
// register cCts category descriptions
// регистрируем описания категории cCts
HRESULT RegisterCategories([in] ULONG cCts,
[in, size_is(cCts)] CATEGORYINFO rgCatInfo[]);
// unregister cCategories category descriptions
// отменяем регистрацию описаний категории
cCategories HRESULT UnRegisterCategories([in] ULONG cCategories,
[in, size_is(cCategories)] CATID rgcatid[]);
// indicate a class implements one or more categories
// показываем, что класс реализует одну или более категорий
HRESULT RegisterClassImplCategories([in] REFCLSID rclsid,
[in] ULONG cCategories,
[in, size_is(cCategories)] CATID rgcatid[]);
// deindicate a class implements one or more categories
// перестаем показывать, реализует класс одну или более категорий
HRESULT UnRegisterClassImplCategories([in] REFCLSID rclsd,
[in] ULONG cCategories,
[in, size_is(cCategories)] CATID rgcatid[]);
// indicate a class requires one or more categories
// показываем, что класс требует одну или более категорий
HRESULT RegisterClassReqCategories([in] REFCLSID rclsid,
[in] ULONG cCategories,
[in, size_is(cCategories)] CATID rgcatid[]):
// deindicate a class requires one or more categories
// перестаем показывать, требует ли класс одну или более категорий
HRESULT UnRegisterClassReqCategones([in] REFCLSID rclsid,
[in] ULONG cCategories,
[in, size_is(cCategories)] CATID rgcatid[]); }



Для определяемых пользователем СОМ-классов нет необходимости реализовывать этот интерфейс. Он существует единственно для того, чтобы серверы смогли сами зарегистрировать свои категории компонентов с использованием реализации предоставляемого СОМ менеджера категорий компонентов.
В случае примера с Chimp следующий код зарегистрирует правильную информацию о каждой категории:
// get the standard category manager
// получим стандартный менеджер категорий
ICatRegister *pcr = 0; HRESULT hr = CoCreateInstance(
CLSID_StdComponentCategoriesMgr, 0,
CLSCTX_ALL, IID_ICatRegister, (void**)&pcr); if (SUCCEEDED(hr)) {
// build descriptions of each category
// формируем описания каждой категории
CATECORYINFO rgcc[4];
rgcc[0].catid = CATID_Simian;
rgcc[1].catid = CATID_Mammal;
rgcc[2].catid = CATID_HasOxygen;
rgcc[3].catid = CATID_HasWater;
rgcc[0].lcid = rgcc[1].lcid = rgcc[2].lcid = rgcc[3].lcid = 0х409;
wcscpy(rgcc[0].szDescription, OLESTR(«Eats Bananas»));
wcscpy(rgcc[1].szDescription, OLESTR(«Bears live young»));
wcscpy(rgcc[2].szDescription, OLESTR(«Provides Oxygen»));
wcscpy(rgcc[3].szDescription, OLESTR(«Provides Water»));
// register information regarding categories
// регистрируем информацию о категориях
pcr->RegisterCategories(4, rgcc);
// note that Chimps are Simians and mammals
// отметим, что Chimps (шимпанзе) являются Simian
// (обезьянами) и Mammal (млекопитающими)
CATID rgcid[2];
rgcid[0] = CATID_Simian;
rgcid[1] = CATID_Mammal;
pcr->RegisterClassImplCategories(CLSID_Chimp, 2, rgcid);
// note that Chimps require Oxygen and Water
// отметим, что Chimps (шимпанзе) нуждаются
// в кислороде (Oxygen) и воде (Water)
rgcid[0] = CATID_HasOxygen;
rgcid[1] = CATID_HasWater;
pcr->RegisterClassReqCategories(CLSID_Chimp, 2, rgcid);
pcr->Release(); }



Заметим, что в этом коде не делается обычных вызовов реестровых API-функций, а вместо них для обработки реестра используется стандартный менеджер категорий.
Кроме того, стандартный менеджер категорий позволяет приложениям запрашивать реестр найти информацию о категориях. Эта функциональная возможность предоставляется через интерфейс ICatInformation :
[object, uuid(0002E013-0000-0000-C000-000000000046)]
interface ICatInformation : IUnknown
{
// get list of known categories
// получаем список известных категорий
HRESULT EnumCategories([in] LCID lcid, [out] IEnumCATEGORYINFO** ppeci);
// get description of a particular category
// получаем описание определенной категории
HRESULT GetCategoryDesc([in] REFCATID rcatid, [in] LCID lcid, [out] OLECHAR ** ppszDesc);
// get list of classes compatible with specified categories
// получаем список классов, совместимых с указанными категориями
HRESULT EnumClassesOfCategories(
[in] ULONG cImplemented,
// -1 indicates ignore
// (-1) означает игнорировать
[in,size_is(cImplemented)] CATID rgcatidImpl[], [in] ULONG cRequired,
// -1 indicates ignore
// (-1) означает игнорировать
[in,size_is(cRequired)] CATID rgcatidReq[], [out] IEnumCLSID** ppenumClsid);
// verify class is compatible with specified categories
// проверяем, совместим ли класс с указанными категориями
HRESULT IsClassOfCategories([in] REFCLSID rclsid,
[in] ULONG cImplemented,
[in,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,size_is(cRequired)] CATID rgcatidReq[]);
// get list of class's implemented categories
// получаем список реализованных категорий класса
HRESULT EnumImplCategoriesOfClass([in] REFCLSID rclsid,
[out] IEnumCATID** ppenumCatid);
// get list of class's required categories
// получаем список категорий, необходимых классу
HRESULT EnumReqCategoriesOfClass([in] REFCLSID rclsid,
[out] IEnumCATID** ppenumCatid);
}



Большинство этих методов возвращают свои курсоры на списки идентификаторов категории или класса. Эти указатели называются нумераторами ( enumerators ) и подробно описываются в главе 7.
Следующий код показывает, как выделить список классов, являющихся членами категории Mammal :
// get the standard category manager // получаем стандартный менеджер категорий
ICatInformation *pci = 0; HRESULT hr = CoCreateInstance(
CLSID_StdComponentCategoriesMgr, 0,
CLSCTX_ALL, IID_ICatInformat1on, (void**)&pci); if (SUCCEEDED(hr)) {
// get the classes that are Simians (ignore required cats)
// получаем классы, являющиеся Simian
// (игнорируем требуемые категории)
IEnumCLSID *pec = 0;
CATID rgcid[1];
rgcid[0] = CATID_Simian;
hr = pci->EnumClassesOfCategories(1, rgcid, -1, 0, &pec);
if (SUCCEEDED(hr)) {
// walk list of CLSIDs 64 at a time
// просматриваем список CLSID no 64 за проход
enum { MAX = 64 };
CLSID rgclsid[MAX];
do {
ULONG cActual = 0;
hr = pec->Next(MAX, rgclsid, &cActual);
if (SUCCEEDED(hr)) {
for (ULONG i = 0; i < cActual; i++)
DisplayClass(rgclsid[i]);
}
}
while (hr == S_OK);
pec->Release();
}
pci->Release(); }



Этот фрагмент кода игнорирует то обстоятельство, что клиентская программа может не поддерживать нужные категории результирующего списка классов. Если бы клиент был осведомлен о том, какие локальные категории им поддерживаются, то он мог бы указать список всех поддерживаемых категорий.
Рассмотрим следующий вызов EnumClassesOfCategories :
CATID rgimpl[1]; rgimpl[0] = CATID_Simians;
CATID rgreq[3]; rgreq[0] = CATID_HasWater;
rgreq[1] = CATID_HasOxygen; rgreq[2] = CATID_HasMilk;
hr =pci->EnumClassesOfCategories(1, rgimpl, 3, rgreq, &pec);



Результирующий список классов будет содержать всех приматов ( Simians ), которые не требуют от среды клиента ничего, кроме кислорода ( Oxygen ), воды ( Water ) и молока ( Milk ). Класс Chimp , зарегистрированный ранее, мог бы быть совместимым классом, так как он реализует специфицированную категорию Simian и требует подмножество специфицированных категорий, использованных в запросе.
Заключительным, причем спорным, аспектом категорий компонентов является представление о классе по умолчанию для категории. СОМ допускает регистрацию CATID в качестве CLSID под ключом реестра HKEY_CLASSES_ROOT\CLSID
Для преобразования CATID в CLSID по умолчанию используется средство TreatAs , введенное эмуляцией. Для указания того, что класс Gorilla является классом по умолчанию для Simian , необходимо добавить следующий ключ реестра:
[HKCR\CLSID\{CATID_Simian}\TreatAs] @={CLSID_Gorilla}
Это простое соглашение позволяет клиентам просто использовать CATID там, где ожидаются CLSID :
// create an instance of the default Simian class
// создаем экземпляр класса Simian, принятого по умолчанию
hr = CoCreateInstance(CATID_Simian, 0, CLSCTX_ALL, IID_IApe, (void**)&pApe);



Если для указанной категории не зарегистрировано ни одного класса по умолчанию, то вызов активации даст сбой и вернет REGDB_E_CLASSNOTREG .
Опубликовал Kest July 13 2009 14:20:47 · 0 Комментариев · 6472 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Библия для програ...
Игра PackMan
DateEdit
Дарахвелидзе П., ...
Animation (Пример...
Dnavigator
Delphi. Учимся на...
Применение жадног...
PHP 5
Прграммирование в...
Microsoft SQL Ser...
Редактор текста (...
Графика в проекта...
Binary2XMLDemo (Р...
Flash MP3 Player ...
Проигрыватель Mp3
Мод "register.php...
BSButton
Email
Интерактивный инт...

Топ загрузок
Приложение Клие... 100466
Delphi 7 Enterp... 86644
Converter AMR<-... 20077
GPSS World Stud... 12667
Borland C++Buil... 11760
Borland Delphi ... 8558
Turbo Pascal fo... 7037
Visual Studio 2... 4998
Калькулятор [Ис... 4760
FreeSMS v1.3.1 3541
Случайные статьи
Нам нужна такая ре...
Использование кома...
бронирования авиаб...
Использование мето...
Ввидеоизображение ...
СПОСОБЫ РАСПОЗНАВА...
Система Mach - фун...
Этап 3 - сколемизация
3.3. СПОСОБЫ РАСПО...
Технология HFC и к...
Опыт оптимизации
Управление устройс...
, специализирующая...
Простая ассоциация
Обсуждение структу...
Циклические коды и...
Что такое Emotion ...
Билеты
БИОГРАФИЯ ХАКА
Программа складыва...
Типичные размеры в...
С помощью меню в C...
Integer variable e...
по адресу http://www
Практическая реали...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?