Использование ActiveX-компонентов и COM в Qt
Модуль QAxContainer входит в состав фреймворка ActiveQt. Он предоставляет библиотеку, реализующую подкласс QWidget, QAxWidget, который действует как контейнер для ActiveX-компонентов, и подкласс QObject, QAxObject, который может быть использован для легкого доступа к невизуальным COM-объектам. Скриптинг COM-объектов, встроенных с помощью этих классов, возможен через классы QAxScript, QAxScriptManager и QAxScriptEngine, а набор инструментов упрощает программно-ориентированный доступ к COM-объектам.
Модуль состоит из шести классов:
- QAxBase — абстрактный класс, предоставляющий API для инициализации и доступа к COM-объекту или ActiveX-компоненту.
- QAxObject предоставляет QObject, который оборачивает COM-объект.
- QAxWidget — QWidget, который оборачивает ActiveX-компонент.
- QAxScriptManager, QAxScript и QAxScriptEngine предоставляют интерфейс к Windows Script Host.
Предоставляются примеры приложений, использующие стандартные ActiveX-компоненты для обеспечения функциональности пользовательского интерфейса высокого уровня.
Темы:
Использование библиотеки
Для создания Qt-приложений, способных размещать COM-объекты и ActiveX-компоненты, необходимо связать приложение с модулем QAxContainer путем добавления
QT += axcontainer
в файл .pro приложения.
Распространение приложений QAxContainer
Библиотека QAxContainer является статической, поэтому нет необходимости распространять какие-либо дополнительные файлы при использовании этого модуля. Однако обратите внимание, что двоичные файлы ActiveX-сервера, которые вы используете, могут быть не установлены на целевой системе, поэтому вы должны включить их в свой пакет и зарегистрировать их во время процесса установки вашего приложения.
Инициализация COM-объектов
Для инициализации COM-объекта используйте API QAxBase::setControl() или передайте имя объекта напрямую в конструктор подкласса QAxBase, который вы используете.
Компонент может быть задан в различных форматах, но самый быстрый и мощный формат — использование идентификатора класса (CLSID) объекта напрямую. Идентификатор класса может быть префиксами с информацией о удаленной машине, на которой должен работать объект, и может включать ключ лицензии для лицензионных компонентов.
Типичные сообщения об ошибках
ActiveQt выводит сообщения об ошибках в выходные данные отладки при возникновении ошибок во время выполнения. Обычно для просмотра этих сообщений необходимо запустить программу в отладчике (например, в выводе отладки Visual Studio).
Запрашиваемый компонент не может быть инициализирован
Запрашиваемый компонент в QAxBase::setControl() не установлен в этой системе или недоступен для текущего пользователя.
Компонент может потребовать права администратора или ключ лицензии. Если компонент лицензирован, передайте ключ лицензии в QAxBase::setControl согласно документации.
Доступ к API объекта
ActiveQt предоставляет Qt-API для COM-объекта и заменяет типы данных COM на Qt-эквиваленты.
Существует четыре способа вызова API COM-объекта:
- Генерация C++ пространства имен
- Вызов по имени
- Через скриптовый движок
- Использование собственных COM-интерфейсов
Генерация C++ пространства имен
Для генерации C++ пространства имен для библиотеки типов, к которой вы хотите получить доступ, используйте инструмент dumpcpp. Запустите этот инструмент вручную для библиотеки типов, которую вы хотите использовать, или интегрируйте его в систему сборки, добавив библиотеки типов в переменную TYPELIBS в файле .pro вашего приложения:
TYPELIBS = file.tlb
Обратите внимание, что dumpcpp может не предоставить все API в библиотеке типов.
Включите полученный заголовочный файл в свой код для доступа к API объектов через сгенерированные C++ классы. См. пример Qutlook для получения дополнительной информации.
Вызов по имени
Используйте QAxBase::dynamicCall() и QAxBase::querySubObject(), а также API QObject::setProperty() и QObject::property() для вызова методов и свойств COM-объекта по их имени. Используйте инструмент dumpdoc для получения документации Qt-API для любого COM-объекта и его подобъектов; обратите внимание, что не все API COM-объекта могут быть доступны.
См. пример Media Player для получения дополнительной информации.
Вызов функции через скриптовый движок
Qt-приложение может размещать любой ActiveScript-движок, установленный в системе. Затем скриптовый движок может выполнять скриптовый код, который обращается к COM-объектам.
Для инициализации скриптового движка используйте QAxScriptManager::addObject() для регистрации COM-объектов, к которым вы хотите получить доступ из скрипта, и QAxScriptManager::load() для загрузки скриптового кода в движок. Затем вызовите скриптовые функции с помощью QAxScriptManager::call() или QAxScript::call().
Какие API COM-объекта доступны через скриптинг, зависит от используемого языка скриптов.
Контейнер для тестирования ActiveX ActiveX Test Container демонстрирует загрузку скриптовых файлов.
Вызов функции с использованием собственных COM-интерфейсов
Для вызова функций COM-объекта, к которым невозможно получить доступ ни одним из описанных выше методов, можно напрямую запросить COM-интерфейс с помощью QAxBase::queryInterface(). Для получения C++ определения соответствующих классов интерфейса используйте директиву #import с библиотекой типов, предоставляемой компонентом; см. руководство по вашему компилятору для получения подробностей.
Типичные сообщения об ошибках
ActiveQt выводит сообщения об ошибках в выходные данные отладки при возникновении ошибок во время выполнения. Обычно для просмотра этих сообщений необходимо запустить программу в отладчике (например, в выводе отладки Visual Studio).
QAxBase::internalInvoke: Нет такого метода
QAxBase::dynamicCall() завершился неудачно — прототип функции не соответствовал никакой функции, доступной в API объекта.
Ошибка вызова члена IDispatch: Не хватает необязательного параметра
QAxBase::dynamicCall() завершился неудачно — прототип функции был правильным, но предоставлено недостаточно параметров.
Ошибка вызова члена IDispatch: Несоответствие типов в параметре n
QAxBase::dynamicCall() завершился неудачно — прототип функции был правильным, но параметр с индексом n был неправильного типа и не мог быть приведен к правильному типу.
QAxScriptManager::call(): Ни один скрипт не предоставляет эту функцию
Вы пытаетесь вызвать функцию, предоставляемую движком, который не предоставляет интроспекцию (например, ActivePython или ActivePerl). Вам необходимо вызвать функцию непосредственно на соответствующем объекте QAxScript.
См. также Фреймворк ActiveQt.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.13/activeqt-container.html