![]() |
Home · Examples |
[Previous: QAxContainer Module][Qt's Modules][Next: QtDBus module]
QAxAggregated | |
QAxBindable | |
QAxFactory |
The QAxServer module is part of the Qt Desktop Edition for Windows. It is not part of the Qt Open Source Edition.
Topics:
An out-of-process executable server is generated from a .pro file like this:
TEMPLATE = app CONFIG += qaxserver RC_FILE = qaxserver.rc ...To build an in-process server, use a .pro file like this:
TEMPLATE = lib CONFIG += qaxserver dll DEF_FILE = qaxserver.def RC_FILE = qaxserver.rc ...The files qaxserver.rc and qaxserver.def are part of the framework and can be used from their usual location (specify a path in the .pro file), or copied into the project directory. You can modify these files as long as it includes any file as the type library entry, ie. you can add version information or specify a different toolbox icon.
The qaxserver configuration will cause the qmake tool to add the required build steps to the build system:
To skip the post-processing step, also set the qaxserver_no_postlink configuration.
Additionally you can specify a version number using the VERSION variable, e.g.
TEMPLATE = lib VERSION = 2.5 ...The version number specified will be used as the version of the type library and of the server when registering.
An executable server has the advantage of being able to run as a stand-alone application, but adds considerable overhead to the communication between the COM client and the COM object. If the control has a programming error only the server process running the control will crash, and the client application will probably continue to run. Not all COM clients support executable servers.
An in-process server is usually smaller and has faster startup time. The communication between client and server is done directly through virtual function calls and does not introduce the overhead required for remote procedure calls. However, if the server crashes the client application is likely to crash as well, and not every functionality is available for in-process servers (i.e. register in the COM's running-object-table).
Both server types can use Qt either as a shared library, or statically linked into the server binary.Typical Errors During the Post-Build Steps
For the ActiveQt specific post-processing steps to work the server has to meet some requirements:
To debug your server run it with -dumpidl outputfile and check where it crashes.
Note that no functions of the control are called. The first linking step has to link a dummy type library into the executable that can later be replaced by idc. Add a resource file with a type library to your project as demonstrated in the examples.The Server Executable Is Not a Valid Win32 Application
Attaching the type library corrupted the server binary. This is a bug in Windows and happens only with release builds. "Unable to locate DLL"
The build system needs to run the server executable to generate the interface definition, and to register the server. If a dynamic link library the server links against is not in the path this might fail (e.g. Visual Studio calls the server using the enivronment settings specified in the "Directories" option). Make sure that all DLLs required by your server are located in a directory that is listed in the path as printed in the error message box."Cannot open file ..."
The ActiveX server could not shut down properly when the last client stopped using it. It usually takes about two seconds for the application to terminate, but you might have to use the task manager to kill the process (e.g. when a client doesn't release the controls properly).Implementing Controls
To implement a COM object with Qt, create a subclass of QObject or any existing QObject subclass. If the class is a subclass of QWidget, the COM object will be an ActiveX control.
#include <QWidget>
class MyActiveX : public QWidget
{
Q_OBJECT
The Q_OBJECT macro is required to provide the meta object information about the widget to the ActiveQt framework.
Q_CLASSINFO("ClassID", "{1D9928BD-4453-4bdd-903D-E525ED17FDE5}") Q_CLASSINFO("InterfaceID", "{99F6860E-2C5A-42ec-87F2-43396F4BE389}") Q_CLASSINFO("EventsID", "{0A3E9F27-E4F1-45bb-9E47-63099BCCD0E3}")Use the Q_CLASSINFO() macro to specify the COM identifiers for the COM object. ClassID and InterfaceID are required, while EventsID is only necessary when your object has signals. To generate these identifiers, use system tools like uuidgen or guidgen.
You can specify additional attributes for each of your classes; see Class Information and Tuning for details.
Q_PROPERTY(int value READ value WRITE setValue)Use the Q_PROPERTY() macro to declare properties for the ActiveX control.
Declare a standard constructor taking a parent object, and functions, signals and slots like for any QObject subclass. If a standard constructor is not present the compiler will issue an error "no overloaded function takes 2 parameters" when using the default factory through the QAXFACTORY_DEFAULT() macro. If you cannot provide a standard constructor you must implement a QAxFactory custom factory and call the constructor you have in your implementation of QAxFactory::create.
public: MyActiveX(QWidget *parent = 0) ... int value() const; public slots: void setValue(int v); ... signals: void valueChange(int v); ... };The ActiveQt framework will expose properties and public slots as ActiveX properties and methods, and signals as ActiveX events, and convert between the Qt data types and the equivalent COM data types.
Copyright © 2008 Trolltech | Trademarks | Qt Jambi 4.4.2_01 |