Устанавливающие свойства функции setSpeed и setRadius следуют этому же образцу, и так же работают слоты start и stop, поскольку они изменяют значение свойства running (приложение выполняется).
Осталось рассмотреть еще одну интересную функцию—член класса AxBouncer:
QAxAggregated *AxBouncer::createAggregate
{
return new ObjectSafetyImpl;
}
Функция createAggregate
класса QAxBindable переопределяется. Она позволяет нам реализовать интерфейсы СОМ, которые модуль QAxServer еще не реализовал, или обойти определенные по умолчанию в QAxServer интерфейсы СОМ. Ниже мы делаем это для обеспечения интерфейса IObjectSafety, который используется в Internet Explorer для доступа к свойствам безопасности компонента. Это является стандартным способом устранения непопулярного сообщения об ошибке «Object not safe for scripting» (объект небезопасен при использовании в сценарии) в Internet Explorer.
Ниже приводится определение класса, которое реализует интерфейс IObjectSafety:
01 class ObjectSafetyImpl : public QAxAggregated, public IObjectSafety
02 {
03 public:
04 long queryInterface(const QUuid &iid, void **iface);
Класс 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<IObjectSafety *>(this);
06 } else {
07 return E_NOINTERFACE;
08 }
09 AddRef;
10 return S_OK;
11 }
Функция queryInterface —
чистая виртуальная функция класса QAxAggregated. Она вызывается управляющим объектом СОМ для предоставления доступа к интерфейсу, который обеспечивается подклассом QAxAggregated. Мы должны возвращать E_NOINTERFACE для интерфейсов, которые мы не определили, и также для IUnknown.
Функции GetInterfaceSafetyOptions и SetInterfaceSafetyOptions объявляются в IObjectSafety. Мы реализуем их, чтобы уведомить всех о том, что наш объект безопасен для использования в сценариях.
Давайте теперь рассмотрим main.cpp:
01 #include <QAxFactory>
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.