Справочник по технологии COM
Страница 58. RegisterActlveObject


 

RegisterActlveObject

Регистрирует объект в качестве активного объекта его класса.

HRESULT RegisterActiveObject
(
IUnknown FAR* punk,
REFCLSID relsid,
DWORD dwFlags,
unsigned long FAR* pdwRegister
)

Параметры:

  • punk - Указатель на интерфейс IUnknown активного объекта.
  • relsid - Указатель на CLSID активного объекта.
  • dwFlags - Флаги, управляющие регистрацией объекта. Возможные значения: ACTIVEOBJECT_STRONG и ACTIVEOBJECT_WEAK.
  • pdwRegister - После возврата указывает на описатель, который необходимо передать Revoke-ActiveObject, когда объект перестанет быть активным.

Коды возврата:
Из возвращенного HRESULT получают один из следующих кодов возврата:

Код возврата Значение
S_OK Успех.
Другие коды возврата Ошибка

Комментарии:
Функция RegisterActiveObject регистрирует объект, на который указывает punk, как активный объект заданного rdsid класса. В процессе регистрации объект заносится в таблицу исполняющихся объектов (ROT) — глобальную таблицу, отслеживающую все объекты, которые выполняются в данный момент на компьютере. (Подробнее о таблице исполняющихся объектов см. OLE Programmer's Reference.) Параметр dwFlags задает сильную или слабую регистрацию, что влияет на процесс завершения работы объекта.
В общем случае объекты ActiveX должны вести себя следующим образом:
Если объект видим, то его работа должна завершаться только по явной команде пользователя (например, выбор пункта Exit в меню File) или по эквивалентной команде клиента ActiveX (вызвавшего метод Quit или Exit объекта Application).
Если объект невидим, то его работа должна завершаться только при разрыве последнего внешнего соединения с ним.
Сильная регистрация вызывает для объекта AddRef, увеличивая счетчик ссылок для него (и связанной с ним заглушки) в таблице исполняющихся объектов. Такой объект должен быть явно отозван из таблицы вызовом RevokeActiveObject. По умолчанию используется именно сильная регистрация (ACTIVEOBJECT_STRONG).
Слабая регистрация помещает указатель на объект в таблицу исполняющихся объектов, но не увеличивает его счетчик ссылок. Соответственно при разрыве последнего внешнего соединения с таким объектом OLE освобождает заглушку объекта, и сам объект становится недоступным.
Чтобы гарантированно обеспечить желаемое поведение, следует учитывать не только стандартные действия OLE, но и следующие соображения:
Даже если код создает невидимый объект, этот объект может позднее стать видимым. После этого объект должен оставаться видимым и активным до тех пор, пока не будет получена явная команда на завершение работы. Это может произойти после того, как из кода исчезнут все ссылки на объект.
Другие клиенты ActiveX тоже могут использовать объект. В этом случае код не должен вызывать принудительного завершения работы объекта.
Во избежание конфликтов Вам следует всегда регистрировать объекты ActiveX с помощью ACTIVEOBJECT_WEAK, а для гарантии того, что объект останется активным, вызывать CoLockObjectExternal. CoLockObjectExternal добавляет сильную блокировку, предотвращая тем самым уменьшение счетчика объекта до нуля. Подробную информацию об этой функции см. в OLE Programmer's Reference.
Чаще всего объектам требуется вызывать CoLockObjectExternal, когда они становятся видимыми, чтобы оставаться активными до тех пор, пока пользователь не выдаст команду на завершение работы. Приводимая ниже процедура содержит шаги, которые должен выполнить Ваш код, чтобы работа объекта завершилась корректно.

Для завершения работы активного объекта:

  1. Когда объект становится видимым, выполните следующий вызов, добавляя блокировку за пользователя:
    CoLockObjectExterna(punk, TRUE, TRUE)
    Блокировка сохраняется до тех пор, пока пользователь явно не запросит завершение работы объекта, например, командой Quit или Exit.
  2. Когда пользователь запрашивает завершение работы объекта, снова вызовите CoLockObjectExternal для освобождения блокировки:
    CoLockObjectExternal(punk, FALSE, TRUE)
  3. Вызовите RevokeActiveObject, чтобы сделать объект неактивным.
  4. Для разрыва всех соединений из других процессов вызовите CoDisconnectObject:
    CoDisconnectObject(punk, 0)
    Подробнее эта функция описана в OLE Programmer's Reference.

 
Следующая статья »