Простой пример создания 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

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

См. также

Внешняя компонента печати PDF (Native Win 32/64)

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

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

1500 руб.

17.09.2018    35428    108    127    

112

Внешняя компонента для сканирования (замена TWAIN-компоненты БСП) (Native Win 32/64)

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

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

2400 руб.

12.05.2020    26546    132    99    

84

GGraphics - внешняя компонента для работы с картинками jpg (jpeg), png, bmp, gif, tif

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

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

3600 руб.

02.09.2010    76227    71    255    

189

Внешняя компонента для подключения 1С к телефонии Asterisk

Разработка внешних компонент Телефония, SIP Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Внешняя компонента выполнена по технологии Native API для 1С 8.х, обеспечивает доступ к программным АТС Asterisk (FreePBX, Elastix) через AMI интерфейс. Через него можно управлять многими функциями Asterisk (определение номеров, перевод звонков, набор телефона и т. д.)

2400 руб.

04.05.2018    45303    117    66    

61

QR-код с логотипом компании (обычная и управляемая форма)

Разработка внешних компонент Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Как известно, стремление сделать свою рекламную продукцию запоминающейся и выделяющейся — верный путь к успеху. Сегодня, мы поговорим с вами о том, что можно сделать с обычным черно-белым QR-кодом, чтобы он стал более живым и привлекательным. Если вам не терпится попробовать сделать QR-код с логотипом компании, то эта обработка для вас!

2400 руб.

22.06.2016    30926    4    4    

8

Внешняя компонента 1С и С++. Продолжаем разговор.

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

А давайте запилим 8.3.26 до релиза, или оповещение с сервера...

19.02.2024    4323    starik-2005    29    

53

Внешние компоненты 1С и язык C++

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

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

26.01.2024    5080    starik-2005    32    

40

Внешняя компонента для работы с Apach Kafka

Инструментарий разработчика Разработка внешних компонент Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример взаимодействия 1С с Apach Kafka посредством внешней компоненты, разработанной на основе официальной библиотеки librdkafka (the Apache Kafka C/C++ client library).

22.11.2023    3098    66    ivan1703    26    

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