Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Роджерсон Д. - Основы COM - 2000.pdf
Скачиваний:
412
Добавлен:
13.08.2013
Размер:
2.4 Mб
Скачать

87

Реализация категорий компонентов

Самое приятное в категориях компонентов то, что для их использования Вам не нужно возиться с Реестром самостоятельно. В системах Windows имеется стандартный Диспетчер категорий компонентов (Component Category Manager), который проделает за Вас всю работу. Этот Диспетчер (CLSID_StdComponentCategoryMgr) —

стандартный компонент СОМ, реализующий два интерфейса, ICatRegister и ICatInformation. ICatRegister используется для регистрации и удаления категорий. Он также может использоваться для добавления и удаления компонентов к категории. ICatInformation применяется для получения информации о категориях в системе. С помощью этого интерфейса Вы можете найти:

!" все категории, зарегистрированные в системе; !" все компоненты, принадлежащие данной категории;

!" все категории, к которым принадлежит данный компонент.

Более полная документация Диспетчера категорий компонентов содержится на прилагающемся к книге диске.

Поищите ICatRegister и ICatInformation в файле ACTIVEX.MVB.

С помощью Диспетчера категорий легко добавлять и удалять категории. Использование Диспетчера показано в примере программы из этой главы, который можно найти на диске. Программа выдает список зарегистрированных в системе категорий компонентов, добавляет новую категорию и, наконец, удаляет эту категорию. Если у Вас эта программа не работает, то возможно, что на Вашем компьютере не установлены некоторые файлы. В прилагаемом к примеру файле README указаны файлы, которые могут отсутствовать, и поясняется, как их установить.

Даже если Вам не нужны категории компонентов, данный пример все равно представляет интерес, так как это первый случай использования нами компонента СОМ, реализованного кем-то другим.

OleView

Редактор Реестра показывает Реестр «в чистом виде», что полезно для изучения. Вы должны знать организацию Реестра, чтобы реализовать самостоятельно регистрирующиеся компоненты или клиентов, которые будут опрашивать Реестр. Однако если Вам нужна дополнительная информация об установленных на компьютере компонентах, использование Редактора Реестра может потребовать слишком много времени. Ведь он, по существу, показывает все данные в виде списка CLSID.

Другая программа из Win32 SDK — OleView — представляет информацию на более высоком уровне. Вместо длинного списка CLSID и других GUID OleView отображает деревья, содержащие элементы с дружественными именами. Кроме того, OleView позволяет просматривать категории компонентов, установленных в системе. Для изучения лучше всего запустить OleView и поработать. Я использовал эту программу для проверки моего кода саморегистрации. Если OleView может найти информацию, то, скорее всего, эта информация помещена в правильное место.

Некоторые функции библиотеки COM

Всем клиентам и компонентам СОМ приходится выполнять много типовых операций. Чтобы сделать выполнение этих операций стандартным и совместимым, СОМ предоставляет библиотеку функций. Библиотека реализована в OLE32.DLL. Для статической компоновки с ней Вы можете использовать OLE32.LIB. В этом разделе мы рассмотрим некоторые из важных типовых операций.

Инициализация библиотеки COM

Во-первых, рассмотрим инициализацию самой библиотеки СОМ. Процесс должен вызвать CoInitialize для инициализации библиотеки, прежде чем использовать ее функции (за исключением функции CoBuildVersion, возвращающей номер версии библиотеки). Когда процесс завершает работу с библиотекой СОМ, он должен вызвать CoUninitialize. Прототипы этих функций приведены ниже:

HRESULT CoInitialize(void* reserved);

// Значение параметра должно быть NULL

void CoUninitialize();

 

Библиотека СОМ требует инициализации только один раз для каждого процесса. Много кратные вызовы процессом CoInitialize допустимы, но каждому из них должен соответствовать отдельный вызов CoUninitialize. Если CoInitilialize уже была вызвана данным процессом, то она возвращает не S_OK, а S_FALSE.

Поскольку в данном процессе библиотеку СОМ достаточно инициализировать лишь один раз, и поскольку эта библиотека используется для создания компонентов, компонентам в процессе не требуется инициализировать библиотеку. По общему соглашению СОМ инициализируется в EXE, а не в DLL.

88

Использование OleInitialize

OLE, построенная «поверх» СОМ, добавляет поддержку библиотек типов, буфера обмена, перетаскивания мышью, документов ActiveX, Автоматизации и управляющих элементов ActiveX. Библиотека OLE содержит дополнительную поддержку этих возможностей. Если Вы хотите использовать все это, следует вызывать

OleInitialize и OleUninitialize вместо CoInitialize и CoUninitialize. Обычно проще всего вызвать функции Ole* и

забыть о них. Функции Ole* вызывают соответствующие функции Com*. Однако использование Ole* вместо Com* приводит к излишним расходам ресурсов и времени, если расширенные возможности не используются.

CoInitializeEx

В операционных системах Windows, поддерживающих DCOM, Вы можете использовать CoInitializeEx, чтобы пометить компонент как использующий модель свободных потоков (free-threaded). Более подробная информация о CoInitializeEx содержится в гл. 12.

Управление памятью

Очень часто внутренняя функция компонента выделяет блок памяти, который возвращается клиенту через выходной параметр. Но кто и каким образом будет эту память освобождать? Наибольшая проблема связана с тем, кто освободит память, — ведь клиент и компонент могут быть реализованы разными людьми, написаны на разных языках и даже выполняться в разных процессах. Необходим стандартный способ выделения и освобождения такой памяти.

Решение предоставляет менеджер памяти задачи (task memory allocator) СОМ. С его помощью компонент может передать клиенту блок памяти, который тот будет в состоянии освободить. Кроме того, менеджер «гладко» работает с потоками, поэтому его можно применять в многопоточных приложениях.

Как обычно, менеджер используется через интерфейс. В данном случае интерфейс называется Imalloc и возвращается функцией CoGetMalloc. IMalloc::Alloc выделяет блок памяти, а IMalloc::Free освобождает память, выделенную с помощью IMalloc::Alloc. Однако обычно вызывать CoGetMalloc для получения указателя на интерфейс, вызывать с помощью этого указателя функцию и затем освобождать указатель — значит делать слишком много работы. Поэтому библиотека СОМ предоставляет удобные вспомогательные функции —

CoTaskMemAlloc и CoTaskMemFree:

void* CoTaskMemAlloc(

ULONG cb // Размер выделяемого блока в байтах

};

void CoTaskMemFree(

void* pv // Указатель на освобождаемый блок памяти

};

Память, выделенную и переданную при помощи выходного параметра, всегда освобождает вызывающая процедура (пользующаяся CoTaskMemFree).

Преобразование строк в GUID

В Реестре содержатся строковые представления CLSID. Поэтому нам нужны специальные функции для преобразования CLSID в строку и обратно. В библиотеке СОМ имеется несколько удобных функций такого рода. StringFromGUID2 конвертирует GUID в строку:

wchar_t szCLSID[39];

int r = ::StringFromGRUID2(CLSID_Component1, szCLSID, 39);

StringFromGUID2 генерирует строку символов Unicode, т.е. строку двухбайтовых символов типа wchar_t, а не char. В системах, не использующих Unicode, Вам придется преобразовать результат в char. Для этого можно прибегнуть к функции ANSI wcstombs, как показано ниже.

#ifndef _UNICODE

// Преобразование из строки Unicode в обычную char szCLSID_single[39]; wcstombs(szCLSID_single, szCLSID, 39);

#endif

Есть еще несколько функций, выполняющих аналогичные операции:

Функция Назначение

StringFromCLSID

Безопасное с точки зрения приведения типов преобразование CLSID

 

в строку

Соседние файлы в предмете Программирование на C++