![]() |
Главная · Все классы · Основные классы · Классы по группам · Модули · Функции | ![]() |
[Предыдущая: Модуль QAxContainer] [Модули Qt] [Следующая: Модуль QtDBus]
The QAxServer module is a Windows-only static library that you can use to turn a standard Qt binary into a COM server. Далее...
The QAxServer module is part of the ActiveQt framework. Оно состоит из трех классов:
Предоставляются несколько примеров реализации элементов управления ActiveX и COM-объектов.
The QAxServer module is part of the Qt Desktop Edition for Windows. It is not part of the Qt Open Source Edition.
Темы:
To turn a standard Qt application into a COM server using the QAxServer library you must add qaxserver as a CONFIG setting in your .pro file.
Внепроцессный исполняемый исполняемый файл сервера генерируется из .pro файла примерно так:
TEMPLATE = app CONFIG += qaxserver RC_FILE = qaxserver.rc ...
Чтобы собрать внутрипроцессный сервер используйте .pro файл, например так:
TEMPLATE = lib CONFIG += qaxserver dll DEF_FILE = qaxserver.def RC_FILE = qaxserver.rc ...
Файлы qaxserver.rc и qaxserver.def являются частью каркаса и могут быть использованы из своих обычных мест расположения (путь указывается в .pro файле) или скопированы в каталог проекта. Вы можете изменять эти файлы до тех пор, пока они включают в себя любой файл как запись библиотеки типов, т.е. вы можете добавить информацию о версии или указать другую пиктограмму панели инструментов.
Конфигурация qaxserver вынудит инструмент qmake добавить требуемые шаги сборки к системе сборки:
Note that the QAxServer build system is not supported on Windows 98/ME (attaching of resources to a binary is not possible there), but a server built on Windows NT/2000/XP will work on previous Windows versions as well.
Чтобы пропустить этап постобработки установите также конфигурацию qaxserver_no_postlink.
Дополнительно вы можете указать номер версии используя переменную VERSION, например
TEMPLATE = lib VERSION = 2.5 ...
Указанный номер версии будет использовать в качестве версии библиотеки типов и сервера при регистрации.
Будет ли ваш COM-сервер запущен как автономный исполняемый файл или как разделяемая библиотека в процессе клиента зависит главным образом от типа COM-объектов которые вы хотите предоставить в сервере.
Исполняемый файл сервера имеет преимущество being able to запущен как автономное приложение, но добавляет значительные накладные расходы на связь между клиентом COM и COM-объектом. Если в элементе управления происходит программная ошибка, то только запущенный элементом управления серверный процесс аварийно завершит работу, а клиентское приложение скорее всего продолжит работу. Не все клиенты COM поддерживают исполняемые файлы серверов.
Внутрипроцессный сервер обычно меньше по размеру и быстрее запускается. Связь между клиентом и сервером выполняется непосредственно через вызовы виртуальных функций и не привносит накладные расходы требуемые для удаленных вызовов процедур. Однако, если сервер аварийно завершит работу клиентское приложение вероятно также аварийно заверится, и не вся функциональность доступна для внутрипроцессных серверов (т.е., регистрация в таблице исполняющихся объектов COM).
Оба типа серверов могут использовать Qt либо как разделяемую библиотеку, либо статически слинкованную в серверную библиотеку.
Для связанных с ActiveQt шагов постобработки для работы сервера нужно удовлетворить некоторые требования:
Если эти требования не выполнены, то возможно произойдет одна или более из следующих ошибок:
Чтобы сгенерировать IDL виджетов, открытых как элементы управления ActiveX, необходимо создать экземпляр класса (вызывается конструктор). На этой стадии не существует ничего кроме объекта QApplication. Конструктор вашего виджета не должен полагаться на какие-либо другие созданные объекты, например, он будет проверять на ненулевые указатели.
Чтобы отладить ваш сервер, запустите его с ключом -dumpidl выходной файл и проверьте, где он аварийно завершается.
Обратите внимание на то, что функции элемента управления не вызываются.
Прикрепление библиотеки типов повреждает бинарный файл сервера. Это ошибка в Windows и случается только в релизных сборках.
Первый шаг линковки заключается в линковке пустой библиотеки типов в исполняемый файл, который idc позднее может заменить. Добавим файл ресурса с библиотекой типов к вашему проекту как продемонстрировано в примерах.
Системе сборки нужно запустить исполняемый файл сервера для генерирования определения интерфейса и зарегистрировать сервер. Если динамически слинкованная библиотека, с которой слинкован сервер, не находится в пути это может вызвать аварийное завершение работы (например, вызовы Visual Studio сервера используя установки окружения, указанные в опции "Directories"). Убедитесь, что все DLLки, требуемые вашему серверу, расположены в каталоге, который перечислен в путях как напечатано в окне сообщения ошибки.
Сервер ActiveX не может выключиться когда последний клиенты перестал его использовать. Обычно для завершения приложения требуется около двух секунд, но вы можете использовать диспетчер задач, чтобы убить процесс (например, когда клиент не освобождает элементы управления должным образом).
Чтобы реализовать COM-объект с помощью Qt, создайте подкласс QObject или любой существующий подкласс QObject. Если класс является подклассом QWidget, COM-объект будет элементов управления ActiveX.
#include <QWidget> class MyActiveX : public QWidget { Q_OBJECT
Макрос Q_OBJECT требуется для предоставления каркасу ActiveQt метаобъектной информации о виджете.
Q_CLASSINFO("ClassID", "{1D9928BD-4453-4bdd-903D-E525ED17FDE5}") Q_CLASSINFO("InterfaceID", "{99F6860E-2C5A-42ec-87F2-43396F4BE389}") Q_CLASSINFO("EventsID", "{0A3E9F27-E4F1-45bb-9E47-63099BCCD0E3}")
Используйте макрос Q_CLASSINFO() для указания идентификаторов COM для COM-объекта. ClassID и InterfaceID требуются пока EventsID необходим только когда ваш объект имеет сигналы. Чтобы сгенерировать эти идентификаторы используйте системные инструменты, аналогичные uuidgen или guidgen.
Вы можете указать дополнительные атрибуты для каждого из ваших классов; за подробностями обращайтесь к Информация о классе и настройка.
Q_PROPERTY(int value READ value WRITE setValue)
Используйте макрос Q_PROPERTY() для объявления свойств элемента управления ActiveX.
Объявите стандартный конструктор, получающий родительский объект, и функции, сигналы и слоты аналогичные для любого подкласса QObject.
public: MyActiveX(QWidget *parent = 0) ... int value() const; public slots: void setValue(int v); ... signals: void valueChange(int v); ... };
Каркас ActiveQt открывает свойства и открытые слоты в качестве свойств ActiveX и методы, а сигналы как события ActiveX, а также конвертировать между типами данных Qt и эквивалентными типами данных COM.
Типы данных Qt, поддерживаемых для свойств:
Тип данных Qt | Свойство COM |
---|---|
bool | VARIANT_BOOL |
QString | BSTR |
int | int |
uint | unsigned int |
double | double |
qlonglong | CY |
qulonglong | CY |
QColor | OLE_COLOR |
QDate | DATE |
QDateTime | DATE |
QTime | DATE |
QFont | IFontDisp* |
QPixmap | IPictureDisp* |
QVariant | VARIANT |
QVariantList (то же что и QList<QVariant>) | SAFEARRAY(VARIANT) |
QStringList | SAFEARRAY(BSTR) |
QByteArray | SAFEARRAY(BYTE) |
QRect | Определяемый пользователем тип |
QSize | Определяемый пользователем тип |
QPoint | Определяемый пользователем тип |
Типы данных Qt, которые поддерживаются для параметров сигналов и слотов:
Тип данных Qt | Параметр COM |
---|---|
bool | [in] VARIANT_BOOL |
bool& | [in, out] VARIANT_BOOL* |
QString, const QString& | [in] BSTR |
QString& | [in, out] BSTR* |
QString& | [in, out] BSTR* |
int | [in] int |
int& | [in,out] int |
uint | [in] unsigned int |
uint& | [in, out] unsigned int* |
double | [in] double |
double& | [in, out] double* |
QColor, const QColor& | [in] OLE_COLOR |
QColor& | [in, out] OLE_COLOR* |
QDate, const QDate& | [in] DATE |
QDate& | [in, out] DATE* |
QDateTime, const QDateTime& | [in] DATE |
QDateTime& | [in, out] DATE* |
QFont, const QFont& | [in] IFontDisp* |
QFont& | [in, out] IFontDisp** |
QPixmap, const QPixmap& | [in] IPictureDisp* |
QPixmap& | [in, out] IPictureDisp** |
QList<QVariant>, const QList<QVariant>& | [in] SAFEARRAY(VARIANT) |
QList<QVariant>& | [in, out] SAFEARRAY(VARIANT)* |
QStringList, const QStringList& | [in] SAFEARRAY(BSTR) |
QStringList& | [in, out] SAFEARRAY(BSTR)* |
QByteArray, const QByteArray& | [in] SAFEARRAY(BYTE) |
QByteArray& | [in, out] SAFEARRAY(BYTE)* |
QObject* | [in] IDispatch* |
QRect& | [in, out] struct QRect (user defined) |
QSize& | [in, out] struct QSize (определяется пользователем) |
QPoint& | [in, out] struct QPoint (определяется пользователем) |
Также поддерживаются экспортируемые перечисления и флаги (смотрите Q_ENUMS() и Q_FLAGS()). Внутрипараметрические (in-parameter) типы также поддерживаются как возвращаемые значения.
Свойства и сигналы/слоты, которые имеют параметры, использующие любые другие типы данных, игнорируются каркасом ActiveQt.
COM-объекты может иметь множество подобъектов, которые могут представлять субэлемент COM-объекта. COM-объект, отображающий приложение многодокументной электронной таблицы, может предоставить например один подобъект для каждого листа таблицы.
Any QObject subclass can be used as the type for a sub object in ActiveX, as long as it is known to the QAxFactory. Затем тип можно использовать в свойствах, или в качестве возвращаемого типа или параметра слота.
To make the properties bindable for the ActiveX client, use multiple inheritance from the QAxBindable class:
#include <QAxBindable> #include <QWidget> class MyActiveX : public QWidget, public QAxBindable { Q_OBJECT
When implementing the property write functions, use the QAxBindable class's requestPropertyChange() and propertyChanged() functions to allow ActiveX clients to bind to the control properties.
Чтобы сделать COM-сервер доступны для системы COM нужно его зарегистрировать в системном реестре используя пять уникальных идентификаторов. Эти идентификаторы предоставляются инструментами тип guidgen или uuidgen. Информация о регистрации позволяет COM для локализации бинарного файла, предоставляемого запрашиваемым элементом управления ActiveX, передавать (marshall) вызовы удаленных процедур для элемента управления и прочитать информацию типов о методах и свойствах отрытых элементом управления.
To create the COM object when the client asks for it the server must export an implementation of a QAxFactory. Самым лёгким способом сделать это - использовать набор макросов:
QAXFACTORY_BEGIN("{ad90301a-849e-4e8b-9a91-0a6dc5f6461f}", "{a8f21901-7ff7-4f6a-b939-789620c03d83}") QAXCLASS(MyWidget) QAXCLASS(MyWidget2) QAXTYPE(MySubType) QAXFACTORY_END()
Это экспортирует MyWidget и MyWidget2 как COM-объекты, которые могут быть созданы клиентами COM и будет зарегистрирован MySubType как тип, который может быть использован в свойствах и параметрах MyWidget и MyWidget2.
The QAxFactory class documentation explains how to use this macro, and how to implement and use custom factories.
Для внепроцессных исполняемых файлов серверов вы можете реализовать функцию main() чтобы создать экземпляр объекта QApplication и войти в цикл обработки событий так же как любое обычное приложение Qt. По умолчанию приложение будет запущено как стандартное приложение Qt, но если вы передадите -activex в командной строке то оно будет запущено как сервер ActiveX. Use QAxFactory::isServer() to create and run a standard application interface, or to prevent a stand-alone execution:
#include <QApplication>
#include <QAxFactory>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
if (!QAxFactory::isServer()) {
// create and show main window
}
return app.exec();
}
Этого однако не требуется так как ActiveQt предоставляет реализацию по умолчанию функции main. The default implemenation calls QAxFactory::startServer(), creates a QApplication instance and calls exec().
Чтобы собрать исполняемый файл сервера ActiveX запустите qmake для генерации make-файла, и используйте make-инструмент вашего компилятора как любого другого приложения Qt. Процесс создания будет также регистрировать элементы управления в системном реестре вызывая получившийся исполняемый файл с опцией -regserver командной строки.
Если сервер ActiveX является исполняемым файлом, то поддерживаются следующие опции командной строки:
Опция | Результат |
---|---|
-regserver | Регистрируем сервер в системном реестре |
-unregserver | Отменяем регистрацию сервера в системном реестре |
-activex | Запускаем приложение как ActiveX-сервер |
-dumpidl <file> -version x.y | Записываем IDL сервера в указанный файл. Библиотека типов будет иметь версию x.y |
Внутрипроцессные сервера могут быть зарегистрированы используя инструмент regsvr32, доступный на всех системах Windows.
Перечисленные ошибки компилятора/линкера основаны на таких проблемах компилятора Microsoft Visual C++ 6.0.
When the error occurs in code that uses the QAXFACTORY_DEFAULT() macro, the widget class had no constructor that can be used by the default factory. Либо добавьте стандартный конструктор виджета, либо реализуйте пользовательскую фабрику, которой он не требуется.
When the error occurs in code that uses the QAXFACTORY_EXPORT() macro, the QAxFactory subclass had no appropriate constructor. Предоставьте общий конструктор класса, похожий на
MyFactory(const QUuid &, const QUuid &);
для вашего класса фабрики.
The unique identifiers have not been passed as strings into the QAXFACTORY_EXPORT() or QAXFACTORY_DEFAULT() macro.
The server does not export an implementation of a QAxFactory. Use the QAXFACTORY_EXPORT() macro in one of the project's implementation files to instantiate and export a factory, or use the QAXFACTORY_DEFAULT() macro to use the default factory.
The server exports more than one implementation of a QAxFactory, or exports the same implementation twice. If you use the default factory, the QAXFACTORY_DEFAULT() macro must only be used once in the project. Use a custom QAxFactory implementation and the QAXFACTORY_EXPORT() macro if the server provides multiple ActiveX controls.
Сервера ActiveX написанные с помощью Qt могут использовать Qt либо как разделяемую библиотеку, либо имеют Qt, слинкованную статически в бинарный файл. В результате обоих способов получаются весьма большие пакеты (либо сам бинарный файл сервера становится больше, либо вы поставляет Qt DLL).
Если ваш сервер ActiveX может быть запущен также как автономное приложение, запустите исполняемый файл сервера с параметром командной строки -regserver после установки исполняемого файла на целевой системе. После этого элементы управления, предоставляемые сервером, станут доступными для клиентов ActiveX.
Если ваш сервер ActiveX является частью установочного пакета, то используйте инструмент regsvr32, предоставляемый Microsoft, чтобы зарегистрировать элементы управления в целевой системе. Если этого инструмента нет, загрузите DLL в ваш процесс установки, разрешите символ DllRegisterServer и вызовите функцию:
HMODULE dll = LoadLibrary("myserver.dll");
typedef HRESULT(__stdcall *DllRegisterServerProc)();
DllRegisterServerProc DllRegisterServer =
(DllRegisterServerProc)GetProcAddress(dll, "DllRegisterServer");
HRESULT res = E_FAIL;
if (DllRegisterServer)
res = DllRegisterServer();
if (res != S_OK)
// error handling
Если вы хотите использовать элементы управления вашего сервера в веб-страницах, вам нужно сделать доступным сервер для браузера, используемого для просмотра вашей страницы, и вам нужно указать расположение пакета сервера в вашей странице.
Чтобы указать расположение сервера используйте атрибут CODEBASE тега OBJECT вашего веб-сайта. Значение может указывать на сам файл сервера, на INF-файл, перечисляющий другие файлы требуемые серверу (например, DLL Qt), или сжатый архив CAB.
Файлы INF и CAB документированы почти в каждой доступной книге о программировании ActiveX и COM также, как и в библиотеке MSDN и различных онлайн ресурсах. Примеры включают INF-файлы, которые могут быть использованы для сборки архивов CAB:
Инструмент CABARC от Microsoft легко может генерировать архивы CAB:
cabarc N simpleax.cab simpleax.exe simple.inf
INF-файлы допускают статическую сборку Qt, поэтому зависимости от других DLL не перечисляются в INF-файлах. Чтобы распространить DLLки, от которых зависит сервер ActiveX, вы должны добавить зависимости и предоставить библиотечные файлы с архивом.
Чтобы использовать элементы управления ActiveX, например, для встраивания их в веб-страницу, используйте HTML-тег <object>.
<object ID="MyActiveX1" CLASSID="CLSID:ad90301a-849e-4e8b-9a91-0a6dc5f6461f"> ... <\object>
To initialize the control's properties, use
<object ID=...> <param name="name" value="value"> <\object>
Если веб-браузер поддерживает выполнение скриптов используйте JavaScript, VBScript и формы для сценария элемента управления. The ActiveQt examples include demonstration HTML pages for the example controls.
Нижеследующее в значительной мере базируется на наших экспериментах с элементами управления ActiveX и клиентскими приложениями, и никоим образом не являются исчерпывающими.
Эти стандартные приложения работают с элементами управления ActiveX, разработанными с помощью ActiveQt. Обратите внимание на то, что некоторые клиенты поддерживают только внутрипроцессные элементы управления.
Приложения Microsoft Office поддерживаются, но вам нужно зарегистрировать элементы управления как "Insertable" объекты. Повторно реализуйте QAxFactory::registerClass чтобы добавить этот атрибут к классу COM, или установите "Insertable" информацию класса для вашего класса равной "yes" используя макрос Q_CLASSINFO.
Мы не сумели заставить работать COM-объекты, основанные на ActiveQt, со следующими клиентскими приложениями.
Если система не может запустить сервер (проверьте с помощью менеджера задач запущен ли процесс сервера), убедитесь что DLL, от которых зависит сервер, присутствуют в системных путях (например, Qt DLL!). Используйте dependency walker чтобы увидеть все зависимости бинарного файла сервера.
Если сервер запущен (например, есть в списке менеджера задач), информацию по отладке вашего сервера смотрите в следующем разделе.
Если сервер может быть собран и правильно зарегистрирован во время процесса сборки, но объект не может быть инициализирован, например, приложение OLE/COM Object Viewer, убедитесь, что DLL, от которых зависит сервер, присутствуют в системных путях (например, Qt DLL). Используйте dependency walker чтобы увидеть все зависимости бинарного файла сервера.
Если сервер запущен, информацию по отладке вашего сервера смотрите в следующем разделе.
Чтобы отладить внутрипроцессный сервер в Visual Studio установите проект сервера в качестве активного проекта и укажите клиент "executable for debug session" в настройках проекта (например, используйте Тестовый контейнер ActiveX). Вы можете установить точки останова в вашем коде, а также пройти по шагам код ActiveQt и Qt если вы установили отладочную версию.
Для отладки исполняемого файла сервера запустите приложение в отладчике и начните с параметра командной строки -activex. Затем запустите своего клиента и создайте экземпляр вашего элемента управления ActiveX. COM будет использовать существующий процесс для следующего клиента пытающегося создать элемент управления ActiveX.
Чтобы предоставить атрибуты для каждого класса COM используйте макрос Q_CLASSINFO, являющийся частью мета-объектной системы Qt.
Ключ | Смысл значения |
---|---|
Версия | Версия класса (по умолчанию 1.0) |
Описание | Строка описания класса. |
ClassID | Идентификатор класса. Вы должны повторно реализовать QAxFactory::classID если не задан. |
InterfaceID | Идентификатор интерфейса. Вы должны повторно реализовать QAxFactory::interfaceID если не задан. |
EventsID | Идентификатор интерфейса события. Нет сигналов, открытых как события COM, если не указано. |
DefaultProperty | Свойство, задающее представление свойства этого класса по умолчанию. Т.е. свойство кнопки по умолчанию будет "text". |
DefaultSignal | Сигнал, задающий представление сигнала этого класса по умолчанию. Т.е. сигнал кнопки по умолчанию будет "clicked". |
LicenseKey | Создание объекта требует указания лицензионного ключа. Ключ может быть пустым что требует лицензионный механизм. По умолчанию классы не лицензированы. Смотрите также следующий раздел. |
StockEvents | Объекты делают видимыми события запаса если значение равно "yes". See QAxFactory::hasStockEvents() |
ToSuperClass | Объекты делают видимыми функциональность всех суперклассов выше по иерархии и включая класс с именем в значении. See QAxFactory::exposeToSuperClass() |
Insertable | Если значение равно "yes", класс регистрируется как "Insertable" и будет приведён в списке контейнеров OLE 2 (т.е. Microsoft Office). Этот атрибут по умолчанию не установлен. |
Aggregatable | Если значение равно "no", класс не поддерживают агрегацию. По умолчанию агрегация поддерживается. |
Creatable | Если значение равно "no", класс не может быть создан клиентом и доступен только через API другого класса (т.е. класс является подтипом). |
RegisterObject | Если значение равно "yes", объекты этого класса регистрируются с помощью OLE и доступны из таблицы запущенных объектов (т.е. клиенты могут присоединиться к уже запущенному экземпляру объекта этого класса). Этот атрибут поддерживается только во внепроцессных серверах. |
MIME | Объект может обработать данные и файлы формата, указанного в значении. Значение имеет формат mime:extension:description. Множественные форматы разделяются точкой с запятой. |
CoClassAlias | Имя класса, используемого в сгенерированном IDL и в реестре. Это особенно useful for C++ classes that live in a namespace - by default, ActiveQt just removes the "::" to make the IDL compile. |
Обратите внимание на то, что и ключи, и значения являются чувствительными к регистру.
Нижеследующее объявляет версию 2.0 класса, который делает видимым только свой собственный API, и доступен в диалоге "Insert Objects" приложений Microsoft Office.
class MyActiveX : public QWidget { Q_OBJECT Q_CLASSINFO("Version", "2.0") Q_CLASSINFO("ClassID", "{7a4cffd8-cbcd-4ae9-ae7e-343e1e5710df}") Q_CLASSINFO("InterfaceID", "{6fb035bf-8019-48d8-be51-ef05427d8994}") Q_CLASSINFO("EventsID", "{c42fffdf-6557-47c9-817a-2da2228bc29c}") Q_CLASSINFO("Insertable", "yes") Q_CLASSINFO("ToSuperClass", "MyActiveX") Q_PROPERTY(...) public: MyActiveX(QWidget *parent = 0); ... };
Если вы разрабатываете компоненты, вы может захотеть контролировать кто может создавать экземпляры этих компонентов. Поскольку бинарный файл сервера может распространяться и регистрироваться на любой клиентской машине, любой может использовать эти компоненты в своём программного обеспечении.
Лицензирование компонентов может быть произведено используя разнообразные приёмы, например, код создания элемента управления может предоставлять лицензионный ключ или механизм, в котором предполагается запускать элемент управления, требует лицензирования.
Чтобы пометить класс Qt как лицензированный укажите "LicenseKey" используя макрос Q_CLASSINFO().
class MyLicensedControl : public QWidget { Q_OBJECT Q_CLASSINFO("LicenseKey", "<key string>") ... };
Ключ требуется чтобы иметь возможность создать экземпляр класса MyLicensedControl на машине, которая не лицензирует сам сеяб. Лицензированный разработчик теперь может повторно распространять бинарный файл сервера со своим приложением, которое создаёт элемент управления используя значение "LicenseKey" до тех пор, пока пользователи приложения не смогут создать элемент управления мез лицензионного ключа.
Если единственного лицензионного ключа для элемента управления недостаточно (т.е. you want differnet developers to receive different license keys) you can specify an empty key to indicate that the control requires a license, and reimplement QAxFactory::validateLicenseKey() to verify that a license exists on the system (ie. через файл лицензии).
Элементы управления ActiveX, предоставленные серверами ActiveQt, поддерживают минимальный набор интерфейсов COM для реализации спецификаций OLE. When the ActiveX class inherits from the QAxBindable class it can also implement additional COM interfaces.
Create a new subclass of QAxAggregated and use multiple inheritance to subclass additional COM interface classes.
class AxImpl : public QAxAggregated, public ISomeCOMInterface { public: AxImpl() {} long queryInterface(const QUuid &iid, void **iface); // IUnknown QAXAGG_IUNKNOWN // ISomeCOMInterface ... }
Reimplement the QAxAggregated::queryInterface() function to support the additional COM interfaces.
long AxImpl::queryInterface(const QUuid &iid, void **iface) { *iface = 0; if (iid == IID_ISomeCOMInterface) *iface = (ISomeCOMInterface *)this; else return E_NOINTERFACE; AddRef(); return S_OK; }
Поскольку ISomeCOMInterface - подкласс IUnknown, вам нужно реализовать функции QueryInterface(), AddRef() и Release(). Чтобы сделать это используйте макрос QAXAGG_IUNKNOWN в определении вашего класса. If you implement the IUnknown functions manually, delegate the calls to the interface pointer returned by the QAxAggregated::controllingUnknown() function, e.g.
HRESULT AxImpl::QueryInterface(REFIID iid, void **iface) { return controllingUnknown()->QueryInterface(iid, iface); }
Do not support the IUnknown interface itself in your queryInterface() implementation.
Implement the methods of the COM interfaces, and use QAxAggregated::object() if you need to make calls to the QObject subclass implementing the control.
In your QAxBindable subclass, implement QAxBindable::createAggregate() to return a new object of the QAxAggregated subclass.
class MyActiveX : public QWidget, public QAxBindable { Q_OBJECT public: MyActiveX(QWidget *parent); QAxAggregated *createAggregate() { return new AxImpl(); } };
Смотрите также Каркас ActiveQt.
[Предыдущая: Модуль QAxContainer] [Модули Qt] [Следующая: Модуль QtDBus]
Copyright © 2008 Trolltech | Торговые марки | Qt 4.3.5 |