Wiki

ActiveX под Управлением

Volker Hilsheimer

Технология Microsoft COM позволяет использовать приложения и библиотеки компонентов, обеспеченные серверами компонентов, и самим быть серверами компонентов. ActiveX сформирован на технологии общей объектной модели и определяет набор интерфейсов для стороны клиента и для стороны сервера. Эта статья представляет новую ActiveQt структуру, которую обеспечивают модули QAxContainer и QAxServer, входящие в Qt 3.1 для Windows.

Новая поддержка ActiveX в Qt позволяет Windows разработчикам обращаться и использовать элементы управления ActiveX, обеспеченные ActiveX серверами, и превращать их собственные приложения и общедоступные библиотеки в ActiveX сервера. Например, приложение Qt может использовать элементы управления ActiveX Internet Explorer, чтобы обеспечить показ web-страницы и передвижение по ней пользователями. Вместо того, чтобы работать с универсальным API нижнего уровня, обеспеченным Microsoft, разработчики используют QAxWidget класс, чтобы писать стандартный Qt код, используя знакомые методы, типы, сигналы и слоты.

Использование Qt версии ранее 3.1 или универсального ActiveX SDK для создания элементов управления ActiveX очень трудоемко. Поддержка ActiveX в Qt 3.1 разработана, чтобы решить проблемы программирования ActiveX. Это изолирует разработчиков от всех различных видов сгенерированного кода, который обычно является частью ActiveX приложения. Вместо этого, разработчики используют QAxServer модуль, чтобы вставить любой QWidget класс как таблицу скриптов элементов управления ActiveX.

Использование элемента управления ActiveX

QAxWidget класс использует интерфейсы самоанализа COM (например. IDispatch), чтобы генерировать информацию мета объекта Qt для элемента управления ActiveX, инициализированного с помощью:

#define CLSID_InternetExplorer "{8856F961-340A-11D0-A96B-00C04FD705A2}"
QAxWidget *activeX = new QAxWidget( this ); activeX->setControl( CLSID_InternetExplorer );

Мета-объектная информация добавляет все свойства и методы, объявленные элементом управления ActiveX, как Qt свойства и слоты. Это означает, что мы можем использовать механизм сигналов и слотов Qt с элементами управления ActiveX. Например, метод GoHome() в Internet Explorer становится слотом GoHome () в Qt:

connect( homeButton, SIGNAL(clicked()), activeX, SLOT(GoHome()) );

Если элемент управления ActiveX предоставляет источник событий, объект QAxWidget регистрирует себя как перехватчик событий, и делает события доступными как Qt сигналы. Qt-ActiveX структура обрабатывает все преобразования типов между COM и Qt типами данных.

connect( activeX, SIGNAL(TitleChange(const QString&)),
		 this, SLOT(setTitle(const QString&)) );

ActiveX события можно использовать подобно любым другим Qt сигналам. В этом примере мы связали событие Internet Explorer TitleChange с нашим собственным setTitle () слотом.

activeX->dynamicCall( "Navigate(const QString&)", 
                          "http://doc.trolltech.com" );

Функция dynamicCall () позволяет разработчикам вызывать метод в элементе управления ActiveX. Qt-ActiveX структура посылает запрос через интерфейс IDispatch, обеспеченный элементом управления ActiveX после выполнения преобразования типов. Если было сделано много запросов, подход с dynamicCall () может быть неэффективен.

IWebBrowser *webBrowser = 0;
activeX->queryInterface( IID_IWebBrowser, &webBrowser );
if ( webBrowser ) {
	do_something_with( webBrowser );
	webBrowser->Release();
}

QAxWidget класс обеспечивает прямой доступ к элементу управления ActiveX непосредственно черезфункцию queryInterface (). Использование интерфейса COM также полезно для того, чтобы обратиться к методам и свойствам, которые имеют типы данных, которые не могут быть преобразованы Qt-ActiveX структурой, например свойства типа IDispatch *. Отличие от стандартного Qt программирования - то, что мы должны вызвать Release(), когда мы закончили использовать элемент управления.

Создание элемента управления ActiveX Сервер

ActiveQt структура обеспечивает статическую библиотеку, включающую функции, превращающие стандартное приложение Qt или DLL в сервер элементов управления ActiveX. Инструмент компоновки qmake добавляет необходимые модификации к системе компоновки, если список параметров настройки CONFIG в .pro файле включает "activeqt":

CONFIG += activeqt

Каждый класс, унаследовавшийся от QWidget, может быть вставлен сервером как элемент управления ActiveX. Сервер должен обеспечить создание объектов QWidget, когда их требует ActiveX клиент. Чтобы создавать ActiveX сервер, вставляющий только отдельный элемент, достаточно использовать заданную по умолчанию макрокоманду.

#include <qaxfactory.h>
 
QAXFACTORY_DEFAULT( QTetrix, 
                "{852558AD-CBD6-4f07-844C-D1E8983CD6FC}", 
                "{2F5D0068-772C-4d1e-BCD2-D3F6BC7FD315}", 
                "{769F4820-9F28-490f-BA50-5545BD381DCB}", 
                "{5753B1A8-53B9-4abe-8690-6F14EC5CA8D0}", 
                "{DE2F7CE3-CFA7-4938-A9FC-867E2FEB63BA}" );

Если код, показанный выше, добавить к Qt Tetrix примеру (в файл qtetrix.cpp), игра станет ActiveX сервером. Параметры, переданные в макрокоманду - это уникальные идентификаторы, используемые COM, чтобы идентифицировать элемент управления ActiveX, интерфейсы, которые он осуществляет, и информацию о типе. Microsoft поставляет инструменты guidgen, для того, чтобы генерировать такие идентификаторы. Чтобы обеспечивать несколько элементов управления ActiveX, нужно все осуществить вручную. Это можно сделать, наследуя QAxFactory класс и повторно осуществляя виртуальные функции, чтобы возвратить информацию об элементах, которые поддерживаются.

qmake инструмент добавляет шаг сборки после компоновки выполняемой программы с информацией, обеспеченной мета объектной системой Qt, чтобы сгенерировать файл определения интерфейса. Свойства класса, сигналы и слоты будут отображены структурой как свойства общей объектной модели, методы и события будут доступны через Idispatch - интерфейс автоматизации.

Клиенты, использующие элемент управления ActiveX Tetrix, должны быть способны запустить игру, и быть способными читать и записывать текущий счет, например, поддерживать таблицу рекордов.

class QTetrix : public QWidget
{
	Q_OBJECT
	Q_PROPERTY( int score READ score WRITE setScore )
public:
	QTetrix( QWidget *parent = 0, const char *name = 0 );
	int score() const;
public slots:
	void startGame();
	void setScore( int score );
signals:
	void gameOver();
};

Макрокоманда Q_PROPERTY делает счет доступным для системы свойств Qt, и ActiveQt структура отображает его как ActiveX свойство.

Приложения, которые являются ActiveX серверами, могут также быть выполнены как автономные приложения. Следующий код удаляет функциональные возможности виджета, которые могли бы не соответствовать элементам управления ActiveX.

if ( QAxFactory::isServer() )
	quitButton->hide();

Вызов приложения с ключом -regserver регистрирует его так, чтобы оно могло быть использовано ActiveX клиентами.

tetrix -regserver

ActiveX клиент может использовать зарегистрированные элементы, например

<OBJECT ID="QTetrix" width="550" height="370"
CLASSID="CLSID:852558AD-CBD6-4f07-844C-D1E8983CD6FC">
</OBJECT>
<FORM>
<INPUT TYPE="button" VALUE="Start Game..."
onClick="QTetrix.startGame()">
</FORM>

HTML, показанный выше, внедряет управление QTetrix в web-страницу, ипоказывает кнопку "Start Game", которая вызовет слот startGame() виджета QTetrix.

Подведение итогов

QAxContainer модуль обеспечивает классаQAxWidget, подкласс QWidget. QAxWidget делает ActiveX методы, свойства и события, доступные как Qt слоты, свойства и сигналы так, чтобы разработчики могли использовать элементы управления ActiveX точно так же, как стандартные QObject. QAxServer модуль обеспечивает интерфейс между Qt виджетами и элементами управления ActiveX. Это включает QAxFactory класс, который используется, чтобы создать ActiveX компоненты. Виджеты и компоненты, созданные с QAxServer модулем, могут быть инстанциированы и использоваться как стандартные элементы управления клиентскими ActiveX приложениями и механизмами создания сценария типа Internet Explorer и Visual Basic.