Простой пример создания ActiveX-control на Qt

25.02.13

Разработка - Разработка внешних компонент

Мне была поставлена задача разработать некий ActiveX-control. Так как основным языком программирования для разработки у нас используется C++, то C# не рассматривался. Я решил выбрать Qt, так как он мне интересен.

Создание ActiveX объектов на Qt достаточно простой процесс, в примерах к QtCreator есть несколько вариантов, показывающих как можно использовать ActiveQt (например этот).

При написании компонента пришлось много времени потратить на поиск ответов на казалось бы простые вопросы, по крупицам их собирать. В результате я получил, что требовалось и решил написать простой пример, чтобы ускорить процесс старта разработки ActiveX-control другим.

Сразу обращу внимание, что не описываю всю технологию ActiveQt, подробную информацию можно получить в документации Qt Assistant и в интернете (например здесь), это пример и пара интересных на мой взгляд моментов.

Начало


Итак, для начала устанавливаем QtSDK (я выбрал коммерческую версию в связке с MS VisualStudio 2010). 

Создаем пустой проект. В качестве примера создадим ActiveX-control с цифровыми часами (возьмем пример отсюда).

Добавляем в наш проект класс цифровых часов. 
Добавляем файл main.cpp, в нем создадим класс, унаследованный от QAxFactory. Этот класс реализовывает фабрику, предоставляющую информацию об элементах управления и создает их по запросу.

#include 
#include "clock.h" // заголовочный файл класса цифровых часов
 
class ActiveQtFactory : public QAxFactory
{
public:
ActiveQtFactory( const QUuid &lib, const QUuid &app )
: QAxFactory( lib, app )
 
{}
// список импортируемых классов
QStringList featureList() const
{
QStringList list;
// если классов будет несколько, то нужно будет добавить в список имя каждого
// в данном пример только один "Clock"
list << "Clock";
return list;
}
// создание объекта экспортируемого класса
QObject *createObject(const QString &key)
{
if ( key == "Clock" )
return new Clock();
// аналогично для каждого класса
return 0;
}
// получение мета-информации о классе
const QMetaObject *metaObject( const QString &key ) const
{
if ( key == "Clock" )
return &Clock::staticMetaObject;
// аналогично для каждого класса
return 0;
}
};
 
// экспорт фабрики
QAXFACTORY_EXPORT( ActiveQtFactory, "{c1de5776-a143-4884-89fc-81a06d04e87d}", "{11403913-dc94-484a-af5a-521f0e93d2ee}" )
 

Если захотим в библиотеку добавить другие классы, то нужно подключить их заголовочные файлы и добавить описание в класс ActiveQtFactory


Теперь доработаем класс Clock для экспортирования его метаданных:
В заголовок добавим макрос для динамической библиотеки

// ...........
#include 
 
#if defined(Clock_LIBRARY)
# define Clock_LIBRARY Q_DECL_EXPORT
#else
# define Clock_LIBRARY Q_DECL_IMPORT
#endif
 
class Clock_LIBRARY Clock : public QLCDNumber
{
// ...........

Добавим информацию о классе 

    // ..............
    Q_OBJECT
    Q_CLASSINFO("ClassID", "{1edd41d0-e01f-445d-9b4e-78c99ab93acf}")
    Q_CLASSINFO("InterfaceID", "{8adccb5c-567e-42f6-8b81-f6634409fb1a}")
    Q_CLASSINFO("EventsID", "{f0a4474f-8c0c-4cdf-985d-8379b26bdd19}")
    // ..............

Для каждого класса необходимо указывать свои ClassID, InterfaceID, EventsID.

Заключительный момент, скорректируем файл проекта

TEMPLATE = lib
CONFIG	+= qt qaxserver dll
contains(CONFIG, static):DEFINES += QT_NODLL
 
SOURCES	 = main.cpp 
   clock.cpp
 
HEADERS +=     
   clock.h
 
DEF_FILE = qaxserver.def
DEFINES += clock_LIBRARY
VERSION = 0.0.0.1
 
# Подключаем заголовочные файлы библиотеки
INCLUDEPATH += clock
TARGET	 = clock

Компилируем, получаем библиотеку.
Это все описано в документации, теперь несколько дополнений, ради которых собственно я и решил написать статью.

Добавить свойство

Необходимо добавить экспортное свойство класса. Для примера возьмем некое name;
Доработаем класс Clock

// .................
    Q_OBJECT
    Q_CLASSINFO("ClassID", "{1edd41d0-e01f-445d-9b4e-78c99ab93acf}")
    Q_CLASSINFO("InterfaceID", "{8adccb5c-567e-42f6-8b81-f6634409fb1a}")
    Q_CLASSINFO("EventsID", "{f0a4474f-8c0c-4cdf-985d-8379b26bdd19}")
    // добавим свойство name
    Q_PROPERTY(QString name READ getName WRITE setName)
 
public:
   // функция получения свойства 
    QString getName()const
    {
        if(name.isEmpty())
            return "Clock";
        else
            return name;
    }
   // функция установки свойства
    void setName(const QString &inName){name = inName;}
private:
    QString name;
// .......

Добавить метод

Методы добавляются через публичные слоты в классе Clock:

// .......
public slots:
    void function(int a);
    QString functionb(const QString &b);
// .......

Добавить событие

Событие, реакцию на которое вы хотите реализовать в алгоритме использующем AXControl, добавляется через сигналы, ниже пример, правда из другого класса:

// в классе создаем сигнал
signals:
    void mouseDbClick(int x, int y);
 
// переопределяем событие
protected:
 
    void mouseDoubleClickEvent(QMouseEvent *event) 
    {
        QPoint pos = event->pos();
        emit mouseDbClick(pos.rx(), pos.ry());
    }

Заключение


Библиотека Qt отличная вещь, может очень многое, нужно учится ее готовить. 

Отдельная благодарность автору статьи о создании динамических библиотек Qt.
Полезные ресурсы, которые помогли в решении задачи doc.crossplatform.ru/qt и qt-project.org

Моя статья на хабре

См. также

Разработка внешних компонент Программист Платформа 1С v8.3 Платформа 1C v8.2 Платные (руб)

Внешняя компонента, позволяющая посылать команды и получать ответы по GraphQL протоколу из 1С.Может быть использована при интеграции. В 1С работает на стороне "клиента".

4600 руб.

27.06.2023    3805    3    0    

5

Разработка внешних компонент Программист Платформа 1С v8.3 1C:Бухгалтерия Платные (руб)

Позволяет автоматизировать работу с картинками. С помощью компоненты можно измерять размер изображений, поворачивать их, наносить водяные знаки, конвертировать из одного формата в другой. Будет очень полезна для интернет-магазинов и всех, кому постоянно требуется работать с различными графическими форматами. Выполнена по технологии NativeAPI. Работает с форматами: jpg (jpeg), png, bmp, gif, tif

3600 руб.

02.09.2010    77773    73    257    

191

Разработка внешних компонент Программист Платформа 1С v8.3 1C:Бухгалтерия Платные (руб)

Внешняя компонента позволяет печатать PDF файлы непосредственно из 1С, не используя при этом сторонних программ. Прекрасно работает на сервере, тонком клиенте и веб-клиенте. Основана на проекте PDFium из состава проекта Chromium/Chrome

1500 руб.

17.09.2018    37125    115    128    

116

Разработка внешних компонент Программист Платформа 1С v8.3 1C:Бухгалтерия 1С:Управление торговлей 11 Платные (руб)

Внешняя компонента для конвертации PDF файлов в картинки без использования дополнительных программ. Работает на сервере и в тонком клиенте.

2400 руб.

25.06.2024    1304    3    4    

3

Разработка внешних компонент Системный администратор Программист Стажер Бесплатно (free)

Библиотека для работы с базами SQLite из 1С на основе внешней компоненты. Для Linux и Windows, бесплатно и с открытым исходным кодом!

14.01.2025    2612    bayselonarrend    14    

48

Разработка внешних компонент Программист Платформа 1С v8.3 1C:Бухгалтерия Россия Бесплатно (free)

В статье описывается приложение-конструктор внешних компонент (native API). Конструктор упрощает процесс разработки за счет удобного добавления всех нужных функций и процедур в графическом режиме, с указанием их параметров и типов параметров. На выходе приложение генерирует готовый код на С++ и Rust и позволяет сразу приступить к реализации, без настройки API компоненты вручную.

04.12.2024    5368    kovalevdmv    26    

77

Разработка внешних компонент Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Некоторые практические аспекты создания внешних компонент на языке С++ для платформы 1С 8.3++.

26.01.2024    7814    starik-2005    40    

47
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. hrip 214 25.02.13 17:17 Сейчас в теме
Qt - хорошая библиотека для разработки приложений.
Самому очень нравится!!! Только жаль совсем нет времени ей заниматься :-(
2. sikuda 678 25.02.13 17:36 Сейчас в теме
Хорошая библиотека. И система привязок более продумана чем обычный интерфейс 1с. Только ActiveQt требует коммерческую лицензию.
Оставьте свое сообщение