📜 ⬆️ ⬇️

A simple example of creating an ActiveX-control on Qt

Introduction


I was given the task to develop a certain ActiveX-control. Since C ++ is used as the main programming language for development, C # was not considered. I decided to choose Qt, since it is interesting to me.

Creating ActiveX objects in Qt is quite a simple process, in the examples for QtCreator there are several options showing how ActiveQt can be used (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 needed and decided to write a simple example to speed up the process of starting ActiveX-control development to others.
')
Immediately I will note that I do not describe the entire ActiveQt technology, detailed information can be obtained from the Qt Assistant documentation and on the Internet (for example, here ), this is an example and a couple of interesting points in my opinion.


Start


So, first 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 clocks 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 controls and creates them on demand.
#include <QAxFactory> #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, then we need to include their header files and add a description to the ActiveQtFactory class.

Now we will modify the class Clock to export its metadata:
Add a macro for the dynamic library to the header.
 // ........... #include <qglobal.h> #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 your ClassID, InterfaceID, EventsID.

The final moment, we will correct 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 a property

You must add an export class property. For example, take some name;
Let's finish the class 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; // ....... 


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 reaction to which you want to implement in the algorithm using AXControl, is added via signals, below is an example 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, maybe a lot, you need to learn how to cook it.

Special thanks to the author of the article on the creation of dynamic libraries Qt.
Useful resources that helped in solving the problem doc.crossplatform.ru/qt and qt-project.org

Source: https://habr.com/ru/post/170607/


All Articles