Использование 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.14/activeqt-container.html