- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Сущность технологии СОМ. Библиотека программиста - Дональд Бокс
Шрифт:
Интервал:
Закладка:
HRESULT CoTreatAsClass([in] REFCLSID rclsidOld, [in] REFCLSID rclsidNew);
Пусть Сhimp2 является новой версией класса Chimp, тогда следующий код проинформирует СОМ, что необходимо переадресовать запросы на активацию Chimp на запросы на активацию Chimp2:
// cause Chimp activation calls to activate Chimp2
// заставим запросы на активацию Chimp активизировать Chimp2
HRESULT hr = CoTreatAsClass(CLSID_Chimp, CLSID_Chimp2);
Эта API-функция добавляет следующий ключ реестра (registry key)
[HKCRCLSID{CLSID_Chimp}TreatAs][1] @={CLSID_Chimp2}
Вызов CoTreatAsClass c CLSID_NULL в качестве второго параметра удаляет настройку TreatAs:
// cause Chimp activation calls to activate Chimps
// заставим запросы на активацию Chimp
// активизировать Chimps
HRESULT hr = CoTreatAsClass(CLSID_Chimp, CLSID_NULL);
Этот запрос восстанавливает исходную реализацию класса в состояние, предшествующее эмуляции. Клиенты могут запросить установку эмуляции данного класса, используя API-функцию CoGetTreatAsClass:
HRESULT CoGetTreatAsClass ([in] REFCLSID rclsidOld, [out] REFCLSID *pclsidNew);
Если запрошенный класс эмулируется другим классом, то CLSID эмулирующего класса будет возвращен посредством второго параметра и вся подпрограмма возвратит S_OK . Если же запрошенный класс не эмулируется другим классом, то посредством второго параметра будет возвращен исходный CLSID и подпрограмма возвратит S_FALSE. Необходимо также отметить, что в момент написания этой книги эмуляция классов не работает должным образом для удаленных запросов на активацию.
Категории компонентов
Как подчеркивалось в этой главе, основные примитивы активации СОМ требуют, чтобы вызывающей программе при создании новых экземпляров класса было известно его точное имя. Иногда, однако, бывает полезно просто потребовать, чтобы подходящим являлся любой класс, удовлетворяющий некоторым семантическим ограничениям. Кроме того, прежде чем сделать запрос на активацию, было бы полезно знать, какие сервисные средства класс требует от своих клиентов. В этом случае не будут создаваться объекты, которые клиент не готов должным образом поддерживать. Эти проблемы послужили причиной для создания категорий компонентов (component categories).
СОМ дает разработчикам возможность группировать родственные СОМ-классы в логические группы, или категории компонентов. Чаще всего все классы внутри категории будут реализовывать один и тот же набор интерфейсов. В то же время простое разделение пространства классов на части по признаку, какие интерфейсы какой класс реализует, не обеспечивает должного уровня модульности для многих приложений. Категории компонентов выступают как метаинформация, показывающая, какие классы совместимы с определенными семантическими ограничениями.
Категория компонентов есть группа логически родственных СОМ-классов, которые разделяют общий ID категории, или CATID. Идентификаторы категории CATID – это GUID, записанные в реестре как атрибуты класса. Каждый класс может иметь два подключа: Implemented Categories и Required Categories (реализованные категории и нужные категории). Представим, что есть две категории компонентов: Simians и Mammals (приматы и млекопитающие). Каждая из этих двух категорий будет иметь уникальный CATID (CATID_Simians и CATID_Mammals соответственно). Допустим, что класс Chimp является членом каждой из этих категорий, и тогда для Chimp ключ реестра Implemented Categories будет содержать в себе каждый GUID как отдельный подключ:
[HKCRCLSID{CLSID_Chimp}Implemented Categories{CATID_Mammals}]
[HKCRCLSID{CLSID_Chimp}Implemented Categories{CATID_Simians}]
Эти элементы реестра обычно добавляются во время саморегистрации. Каждая известная категория компонентов в системе имеет запись в разделе реестра HKEY_CLASSES_ROOTComponent Categories
Каждая категория имеет свой собственный уникальный подключ, названный как CATID. Под этим подключом каждая категория имеет одну или более именованных величин, содержащих текстовое описание этой категории. Например, двум показанным выше категориям понадобятся такие элементы реестра:
[HKCRComponent Categories{CATID_Mammals}] 409="Bears live young"
[HKCRComponent Categones{CATID_Simians}] 409="Eats Bananas"
Отметим, что в этом примере используется величина 409, являющаяся кодом локализации, или локальным идентификатором языка LCID (locale identifier), для U.S.English. Другая местная специфика может поддерживаться путем добавления дополнительных именованных величин.
Классы также могут указать, что они требуют от клиента функциональное назначение определенного типа. Обычно такая поддержка принимает вид узловых интерфейсов (site interfaces), которые клиент предоставляет активированному объекту. Для того, чтобы разделить эти предоставляемые клиентом сервисы на категории, не зависящие от отдельного интерфейса, СОМ позволяет классам объявлять второй тип категорий ID; он может использоваться клиентами для гарантии того, что они не активировали компонент, который не могут должным образом принять. Рассмотрим следующие две категории сервисов, предоставляемых клиентом: CATID_HasOxygen и CATID_HasWater. Поскольку для выживания шимпанзе необходимы кислород и вода, разработчик Chimp должен объявить, что эти две категории сервисов, предоставляемых клиентом, необходимы для активации. Это делается с помощью подключей из Required Categories:
[HKCRCLSID{CLSID_Chimp}Required Categories{CATID_HasOxygen}]
[HKCRCLSID{CLSID_Chimp}Required Categories{CATID_HasWater}]
Кроме того, ID этих двух категорий следует внести в реестр под ключом HKEY_CLASSES_ROOTComponent 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];