A simple example of creating ActiveX-control in Qt
Introduction
I was tasked with developing a certain ActiveX-control. Since we use C ++ as the main programming language for development, C # was not considered. I decided to choose Qt, as it interests me.
Creating ActiveX objects on Qt is a fairly simple process, in the examples for QtCreator there are several options that show how you can use ActiveQt (for example, this one ).
When writing a component, I had to spend a lot of time searching for answers to seemingly simple questions, collecting them bit by bit. As a result, I got what was required and decided to write a simple example to speed up the process of starting ActiveX-control development for others.
I’ll immediately notice that I don’t describe the entire ActiveQt technology, detailed information can be found in the Qt Assistant documentation and on the Internet (for example, here ), this is an example and a couple of points that are interesting in my opinion.
Start
So, for starters, install QtSDK (I chose the commercial version in conjunction with MS VisualStudio 2010).
Create an empty project. As an example, let's create an ActiveX-control with a digital clock (let's take an example from here ).
We add a class of digital watches to our project.
We add the main.cpp file, in it we will create the class inherited from QAxFactory. This class implements a factory that provides information about the controls and creates them upon request.
#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}" )
If we want to add other classes to the library, we need to include their header files and add a description to the ActiveQtFactory class.
Now we ’ll modify the Clock class to export its metadata:
Add a macro for the dynamic library to the header
// ...........
#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
{
// ...........
Add class information
// ..............
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}")
// ..............
For each class, you must specify its own ClassID, InterfaceID, EventsID.
The final point, adjust the project file
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
Compile, get the library.
This is all described in the documentation, now a few additions, for which I actually decided to write an article.
Add Property
You must add the export property of the class. For example, take some name;
Let's modify the Clock class
// .................
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;
// .......
Add method
Methods are added through public slots in the Clock class:
// .......
public slots:
void function(int a);
QString functionb(const QString &b);
// .......
Add Event
The event, the response to which you want to implement in an algorithm using AXControl, is added via signals, below is an example, though from another class:
// в классе создаем сигнал
signals:
void mouseDbClick(int x, int y);
// переопределяем событие
protected:
void mouseDoubleClickEvent(QMouseEvent *event)
{
QPoint pos = event->pos();
emit mouseDbClick(pos.rx(), pos.ry());
}
Conclusion
The Qt library is a great thing, it can do a lot, you need to learn how to cook it.
Special thanks to the author of the article on creating dynamic Qt libraries.
Useful resources that helped in solving the problem doc.crossplatform.ru/qt and qt-project.org