08 HRESULT WINAPI SetInterfaceSafetyOptions(REFIID riid,
09 DWORD pdwSupportedOptions, DWORD pdwEnabledOptions);
10 };
Класс ObjectSafetyImpl наследует как QAxAggregated, так и IObjectSafety. Класс QAxAggregated является абстрактным базовым классом, предназначенным для реализации дополнительных интерфейсов СОМ. Объект СОМ, который расширяет QAxAggregated, доступен при помощи функции controllingUnknown(). Этот объект СОМ создается незаметно для пользователя модулем QAxServer.
Макрос QAXAGG_IUNKNOWN обеспечивает стандартную реализацию функций QueryInterface(), AddRef() и Release(). В этих реализациях просто делается вызов одноименных функций для управляющего объекта СОМ.
01 long ObjectSafetyImpl::queryInterface(const QUuid &iid, void **iface)
02 {
03 *iface = 0;
04 if (iid == IID_IObjectSafety) {
05 *iface = static_cast(this);
06 } else {
07 return E_NOINTERFACE;
08 }
09 AddRef();
10 return S_OK;
11 }
Функция queryInterface() — чистая виртуальная функция класса QAxAggregated. Она вызывается управляющим объектом СОМ для предоставления доступа к интерфейсу, который обеспечивается подклассом QAxAggregated. Мы должны возвращать E_NOINTERFACE для интерфейсов, которые мы не определили, и также для IUnknown.
01 HRESULT WINAPI ObjectSafetyImpl::GetInterfaceSafetyOptions(
02 REFIID /* riid */, DWORD *pdwSupportedOptions,
03 DWORD *pdwEnabledOptions)
04 {
05 *pdwSupportedOptions =
06 INTERFACESAFE_FOR_UNTRUSTED_DATA
07 | INTERFACESAFE_FOR_UNTRUSTED_CALLER;
08 *pdwEnabledOptions = *pdwSupportedOptions;
09 return S_OK;
10 }
11 HRESULT WINAPI ObjectSafetyImpl::SetInterfaceSafetyOptions(
12 REFIID /* riid */, DWORD /* pdwSupportedOptions */,
13 DWORD /* pdwEnabledOptions */)
14 {
15 return S_OK;
16 }
Функции GetInterfaceSafetyOptions() и SetInterfaceSafetyOptions() объявляются в IObjectSafety. Мы реализуем их, чтобы уведомить всех о том, что наш объект безопасен для использования в сценариях.
Давайте теперь рассмотрим main.cpp:
01 #include
02 #include "axbouncer.h"
03 QAXFACTORY_DEFAULT(AxBouncer,
04 "{5e2461aa-a3e8-4f7a-8b04-307459a4c08c}",
05 "{533af11f-4899-43de-8b7f-2ddf588d1015}",
06 "{772c14a5-a840-4023-b79d-19549ece0cd9}",
07 "{dbce1e56-70dd-4f74-85e0-95c65d86254d}",
08 "{3f3db5e0-78ff-4e35-8a5d-3d3b96c83e09}")
Макрос QAXFACTORY_DEFAULT() экспортирует элемент управления ActiveX. Мы можем использовать его для серверов ActiveX, которые экспортируют только один элемент управления. В следующем примере данного раздела будет показано, как можно экспортировать много элементов управления ActiveX.
Первым аргументом макроса QAXFACTORY_DEFAULT() является имя экспортируемого класса Qt. Такое же имя используется для экспорта элемента управления. Остальные пять аргументов следующие: идентификатор класса, идентификатор интерфейса, идентификатор интерфейса событий, идентификатор библиотеки типов и идентификатор приложения. Мы можем использовать стандартные инструментальные средства, например guidgen или uuidgen, для получения этих идентификаторов. Поскольку сервер реализован в виде библиотеки, нам не требуется иметь функцию main().
Ниже приводится файл .pro для внутрипроцессного сервера ActiveX:
TEMPLATE = lib
CONFIG += dll qaxserver
HEADERS = axbouncer.h \
objectsafetyimpl.h
SOURCES = axbouncer.cpp \
main.cpp \