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

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

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Разработка внешних компонент POS терминал Рабочее место Розничная торговля Программист Пользователь 1С:Предприятие 8 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Рестораны, кафе и фаст-фуд Реклама, PR и маркетинг Управленческий учет Платные (руб)

Медиадисплей покупателя может отображать текущую покупку на кассовом месте, показывать видеорекламу, баннеры, во время простоя разворачивать рекламу на весь экран. Экран можно использовать в качестве графического меню-борда в кафе и видеовывески. В качестве устройства отображения можно использовать Android-планшеты, смарт-телевизоры с Android, мониторы или проекторы под управлением Windows или Linux-компьютера. Linux-версия успешно запускается на одноплатных компьютерах Raspberri Pi и Orange Pi. Настраивается ЛЮБОЙ ДИЗАЙН экрана при помощи встроенного графического редактора! Решение можно масштабировать от одного экрана до тысяч экранов с централизованным управлением.

18300 руб.

30.05.2017    56545    10    71    

47

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

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

5084 руб.

17.09.2018    40486    118    128    

120

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

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

5094 руб.

02.09.2010    81549    75    280    

193

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

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

14.01.2025    6210    bayselonarrend    17    

54

Разработка внешних компонент Программист 1С:Предприятие 8 Россия Бесплатно (free)

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

04.12.2024    10925    kovalevdmv    29    

83

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

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

26.01.2024    11453    starik-2005    40    

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