1 /****************************************************************************
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
6 ** This file is part of the documentation of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
17 ** GNU Free Documentation License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Free
19 ** Documentation License version 1.3 as published by the Free Software
20 ** Foundation and appearing in the file included in the packaging of
21 ** this file. Please review the following information to ensure
22 ** the GNU Free Documentation License version 1.3 requirements
23 ** will be met: http://www.gnu.org/copyleft/fdl.html.
26 ****************************************************************************/
29 \page activeqt-server.html
30 \title Building ActiveX servers in Qt
33 \brief A Windows-only static library for turning a Qt binary into a COM server.
35 The QAxServer module is part of the \l ActiveQt framework. It
36 consists of three classes:
39 \o QAxFactory defines a factory for the creation of COM objects.
40 \o QAxBindable provides an interface between the Qt widget and the
42 \o QAxAggregated can be subclassed to implement additional COM interfaces.
45 Some \l{ActiveQt Examples}{example implementations} of ActiveX
46 controls and COM objects are provided.
48 \sa {ActiveQt Framework}
54 \section1 Using the Library
56 To turn a standard Qt application into a COM server using the
57 QAxServer library you must add \c qaxserver as a CONFIG setting
60 An out-of-process executable server is generated from a \c .pro
63 \snippet doc/src/snippets/code/doc_src_qaxserver.pro 0
65 To build an in-process server, use a \c .pro file like this:
66 \snippet doc/src/snippets/code/doc_src_qaxserver.pro 1
68 The files \c qaxserver.rc and \c qaxserver.def are part of the
69 framework and can be used from their usual location (specify a
70 path in the \c .pro file), or copied into the project directory.
71 You can modify these files as long as it includes any file as the
72 type library entry, ie. you can add version information or specify
73 a different toolbox icon.
75 The \c qaxserver configuration will cause the \c qmake tool to add the
76 required build steps to the build system:
79 \o Link the binary against \c qaxserver.lib instead of \c qtmain.lib
80 \o Call the \l idc tool to generate an IDL file for the COM server
81 \o Compile the IDL into a type library using the MIDL tool (part of the
82 compiler installation)
83 \o Attach the resulting type library as a binary resource to the server
84 binary (again using the \l idc tool)
85 \o Register the server
88 To skip the post-processing step, also set the \c qaxserver_no_postlink
91 Additionally you can specify a version number using the \c VERSION
94 \snippet doc/src/snippets/code/doc_src_qaxserver.pro 2
96 The version number specified will be used as the version of the type
97 library and of the server when registering.
99 \section2 Out-of-Process vs. In-Process
101 Whether your COM server should run as a stand-alone executable
102 or as a shared library in the client process depends mainly on the
103 type of COM objects you want to provide in the server.
105 An executable server has the advantage of being able to run as a
106 stand-alone application, but adds considerable overhead to the
107 communication between the COM client and the COM object. If the
108 control has a programming error only the server process running
109 the control will crash, and the client application will probably
110 continue to run. Not all COM clients support executable servers.
112 An in-process server is usually smaller and has faster startup
113 time. The communication between client and server is done directly
114 through virtual function calls and does not introduce the overhead
115 required for remote procedure calls. However, if the server crashes the
116 client application is likely to crash as well, and not every
117 functionality is available for in-process servers (i.e. register in
118 the COM's running-object-table).
120 Both server types can use Qt either as a shared library, or statically
121 linked into the server binary.
123 \section2 Typical Errors During the Post-Build Steps
125 For the ActiveQt specific post-processing steps to work the
126 server has to meet some requirements:
129 \o All controls exposed can be created with nothing but a QApplication
130 instance being present
131 \o The initial linking of the server includes a temporary type
133 \o All dependencies required to run the server are in the system path
134 (or in the path used by the calling environment; note that Visual
135 Studio has its own set of environment variables listed in the
136 Tools|Options|Directories dialog).
139 If those requirements are not met one ore more of the following
140 errors are likely to occur:
142 \section3 The Server Executable Crashes
144 To generate the IDL the widgets exposed as ActiveX controls need to
145 be instantiated (the constructor is called). At this point, nothing
146 else but a QApplication object exists. Your widget constructor must
147 not rely on any other objects to be created, e.g. it should check for
150 To debug your server run it with -dumpidl outputfile and check where
153 Note that no functions of the control are called.
155 \section3 The Server Executable Is Not a Valid Win32 Application
157 Attaching the type library corrupted the server binary. This is a
158 bug in Windows and happens only with release builds.
160 The first linking step has to link a dummy type library into the
161 executable that can later be replaced by idc. Add a resource file
162 with a type library to your project as demonstrated in the examples.
164 \section3 "Unable to locate DLL"
166 The build system needs to run the server executable to generate
167 the interface definition, and to register the server. If a dynamic
168 link library the server links against is not in the path this
169 might fail (e.g. Visual Studio calls the server using the
170 enivronment settings specified in the "Directories" option). Make
171 sure that all DLLs required by your server are located in a
172 directory that is listed in the path as printed in the error
175 \section3 "Cannot open file ..."
177 The ActiveX server could not shut down properly when the last
178 client stopped using it. It usually takes about two seconds for
179 the application to terminate, but you might have to use the task
180 manager to kill the process (e.g. when a client doesn't release
181 the controls properly).
183 \section1 Implementing Controls
185 To implement a COM object with Qt, create a subclass of QObject
186 or any existing QObject subclass. If the class is a subclass of QWidget,
187 the COM object will be an ActiveX control.
189 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 3
191 The Q_OBJECT macro is required to provide the meta object information
192 about the widget to the ActiveQt framework.
194 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 4
196 Use the Q_CLASSINFO() macro to specify the COM identifiers for the COM
197 object. \c ClassID and \c InterfaceID are required, while \c EventsID is
198 only necessary when your object has signals. To generate these identifiers,
199 use system tools like \c uuidgen or \c guidgen.
201 You can specify additional attributes for each of your classes; see
202 \l{Class Information and Tuning} for details.
204 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 5
206 Use the Q_PROPERTY() macro to declare properties for the ActiveX control.
208 Declare a standard constructor taking a parent object, and functions,
209 signals and slots like for any QObject subclass.
211 If a standard constructor is not present the compiler will issue
212 an error "no overloaded function takes 2 parameters" when using
213 the default factory through the QAXFACTORY_DEFAULT() macro. If you
214 cannot provide a standard constructor you must implement a
215 QAxFactory custom factory and call the constructor you have in
216 your implementation of QAxFactory::create.
219 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 6
221 The ActiveQt framework will expose properties and public slots as ActiveX
222 properties and methods, and signals as ActiveX events, and convert between
223 the Qt data types and the equivalent COM data types.
227 The Qt data types that are supported for properties are:
273 COM cannot marshal IPictureDisp accross process boundaries,
274 so QPixmap properties cannot be called for out-of-process servers. You
275 can however marshal the image data via e.g. temporary files. See the
277 \link http://support.microsoft.com/default.aspx?scid=kb;[LN];Q150034 KB article
278 Q150034 \endlink for more information.
284 \o QVariantList (same as QList\<QVariant\>)
285 \o SAFEARRAY(VARIANT)
303 The Qt data types that are supported for parameters in signals and
314 \o [in, out] VARIANT_BOOL*
316 \o QString, const QString&
335 \o [in, out] unsigned int*
343 \o QColor, const QColor&
347 \o [in, out] OLE_COLOR*
349 \o QDate, const QDate&
355 \o QDateTime, const QDateTime&
361 \o QFont, const QFont&
365 \o [in, out] IFontDisp**
367 \o QPixmap, const QPixmap&
368 \o [in] IPictureDisp*
371 \o [in, out] IPictureDisp**
373 \o QList\<QVariant\>, const QList\<QVariant\>&
374 \o [in] SAFEARRAY(VARIANT)
376 \o QList\<QVariant\>&
377 \o [in, out] SAFEARRAY(VARIANT)*
379 \o QStringList, const QStringList&
380 \o [in] SAFEARRAY(BSTR)
383 \o [in, out] SAFEARRAY(BSTR)*
385 \o QByteArray, const QByteArray&
386 \o [in] SAFEARRAY(BYTE)
389 \o [in, out] SAFEARRAY(BYTE)*
396 OLE needs to marshal user defined types by reference (ByRef), and cannot
397 marshal them by value (ByVal). This is why const-references and object
398 parameters are not supported for QRect, QSize and QPoint.
400 \o [in, out] struct QRect (user defined)
403 \o [in, out] struct QSize (user defined)
406 \o [in, out] struct QPoint (user defined)
409 Also supported are exported enums and flags (see Q_ENUMS() and
410 Q_FLAGS()). The in-parameter types are also supported as
413 Properties and signals/slots that have parameters using any other
414 data types are ignored by the ActiveQt framework.
416 \section2 Sub-Objects
418 COM objects can have multiple sub-objects that can represent a sub element
419 of the COM object. A COM object representing a multi-document spread sheet
420 application can for example provide one sub-object for each spread sheet.
422 Any QObject subclass can be used as the type for a sub object in ActiveX, as
423 long as it is known to the QAxFactory. Then the type can be used in properties,
424 or as the return type or paramter of a slot.
426 \section2 Property Notification
428 To make the properties bindable for the ActiveX client, use multiple
429 inheritance from the QAxBindable class:
431 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 7
433 When implementing the property write functions, use the
434 QAxBindable class's requestPropertyChange() and propertyChanged()
435 functions to allow ActiveX clients to bind to the control
438 This is not required, but gives the client more control over
442 \section1 Serving Controls
444 To make a COM server available to the COM system it must be registered
445 in the system registry using five unique identifiers.
446 These identifiers are provided by tools like \c guidgen or \c uuidgen.
447 The registration information allows COM to localize the binary providing
448 a requested ActiveX control, marshall remote procedure calls to the
449 control and read type information about the methods and properties exposed
452 To create the COM object when the client asks for it the server must export
453 an implementation of a QAxFactory. The easist way to do this is to use a set
456 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 8
458 This will export \c MyWidget and \c MyWidget2 as COM objects that can be
459 created by COM clients, and will register \c MySubType as a type that can
460 be used in properties and parameters of \c MyWidget and \c MyWidget2.
462 The \link QAxFactory QAxFactory class documentation \endlink explains
463 how to use this macro, and how to implement and use custom factories.
465 For out-of-process executable servers you can implement a main()
466 function to instantiate a QApplication object and enter the event
467 loop just like any normal Qt application. By default the
468 application will start as a standard Qt application, but if you
469 pass \c -activex on the command line it will start as an ActiveX
470 server. Use QAxFactory::isServer() to create and run a standard
471 application interface, or to prevent a stand-alone execution:
473 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 9
475 This is however not necessary as ActiveQt provides a default implementation
476 of a main function. The default implemenation calls QAxFactory::startServer(),
477 creates a QApplication instance and calls exec().
479 To build the ActiveX server executable run \c qmake
480 to generate the makefile, and use your compiler's
481 make tool as for any other Qt application. The make process will
482 also register the controls in the system registry by calling the
483 resulting executable with the \c -regserver command line option.
485 If the ActiveX server is an executable, the following command line
486 options are supported:
488 \header \o Option \o Result
489 \row \o \c -regserver \o Registers the server in the system registry
490 \row \o \c -unregserver \o Unregisters the server from the system registry
491 \row \o \c -activex \o Starts the application as an ActiveX server
492 \row \o \c{-dumpidl <file> -version x.y} \o Writes the server's IDL to the
493 specified file. The type library will have version x.y
496 In-process servers can be registered using the \c regsvr32 tool available
497 on all Windows systems.
499 \section2 Typical Compile-Time Problems
501 The compiler/linker errors listed are based on those issued by the
502 Microsoft Visual C++ 6.0 compiler.
504 \section3 "No overloaded function takes 2 parameters"
506 When the error occurs in code that uses the QAXFACTORY_DEFAULT()
507 macro, the widget class had no constructor that can be used by the
508 default factory. Either add a standard widget constructor or
509 implement a custom factory that doesn't require one.
511 When the error occurs in code that uses the QAXFACTORY_EXPORT()
512 macro, the QAxFactory subclass had no appropriate constructor.
513 Provide a public class constructor like
515 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 10
517 for your factory class.
519 \section3 "Syntax error: bad suffix on number"
521 The unique identifiers have not been passed as strings into the
522 QAXFACTORY_EXPORT() or QAXFACTORY_DEFAULT() macro.
524 \section3 "Unresolved external symbol _ucm_instantiate"
526 The server does not export an implementation of a QAxFactory. Use
527 the QAXFACTORY_EXPORT() macro in one of the project's
528 implementation files to instantiate and export a factory, or use
529 the QAXFACTORY_DEFAULT() macro to use the default factory.
531 \section3 "_ucm_initialize already defined in ..."
533 The server exports more than one implementation of a QAxFactory,
534 or exports the same implementation twice. If you use the default
535 factory, the QAXFACTORY_DEFAULT() macro must only be used once in
536 the project. Use a custom QAxFactory implementation and the
537 QAXFACTORY_EXPORT() macro if the server provides multiple ActiveX
540 \section2 Distributing QAxServer Binaries
542 ActiveX servers written with Qt can use Qt either as a shared
543 library, or have Qt linked statically into the binary. Both ways
544 will produce rather large packages (either the server binary
545 itself becomes large, or you have to ship the Qt DLL).
547 \section3 Installing Stand-Alone Servers
549 When your ActiveX server can also run as a stand-alone application,
550 run the server executable with the \c -regserver command line
551 parameter after installing the executable on the target system.
552 After that the controls provided by the server will be available to
555 \section3 Installing In-Process Servers
557 When your ActiveX server is part of an installation package, use the
558 \c regsvr32 tool provided by Microsoft to register the controls on
559 the target system. If this tool is not present, load the DLL into
560 your installer process, resolve the \c DllRegisterServer symbol and
563 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 11
565 \section3 Distributing Servers over the Internet
567 If you want to use controls in your server in web-pages you need to
568 make the server available to the browser used to view your page, and
569 you need to specify the location of the server package in your page.
571 To specify the location of a server, use the CODEBASE attribute in
572 the OBJECT tag of your web-site. The value can point to the server
573 file itself, to an INF file listing other files the server requires
574 (e.g. the Qt DLL), or a compressed CAB archive.
576 INF and CAB files are documented in almost every book available about
577 ActiveX and COM programming as well as in the MSDN library and various
578 other Online resources. The examples include INF files that can be used
579 to build CAB archives:
581 \snippet examples/activeqt/simple/simple.inf 0
583 The CABARC tool from Microsoft can easily generate CAB archives:
585 \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 12
587 The INF files assume a static build of Qt, so no dependencies to other DLLs
588 are listed in the INF files. To distribute an ActiveX server depending on
589 DLLs you must add the dependencies, and provide the library files
592 \section1 Using the Controls
594 To use the ActiveX controls, e.g. to embed them in a web page, use
595 the \c <object> HTML tag.
597 \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 13
599 To initialize the control's properties, use
601 \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 14
603 If the web browser supports scripting use JavaScript, VBScript
604 and forms to script the control. The
605 \l{ActiveQt Examples} include demonstration HTML pages for the example
608 \section2 Supported and Unsupported ActiveX Clients
610 The following is largly based on our own experiements with ActiveX
611 controls and client applications, and is by no means complete.
613 \section3 Supported Clients
615 These standard applications work with ActiveX controls developed with
616 ActiveQt. Note that some clients support only in-process controls.
620 \o Microsoft ActiveX Control Test Container
621 \o Microsoft Visual Studio 6.0
622 \o Microsoft Visual Studio.NET/2003
623 \o Microsoft Visual Basic 6.0
624 \o MFC- and ATL-based containers
625 \o Sybase PowerBuilder
626 \o ActiveQt based containers
629 Microsoft Office applications are supported, but you need to register
630 the controls as "Insertable" objects. Reimplement QAxFactory::registerClass
631 to add this attribute to the COM class, or set the "Insertable" class info
632 for your class to "yes" using the Q_CLASSINFO macro.
634 \section3 Unsupported Clients
636 We have not managed to make ActiveQt based COM objects work with the
637 following client applications.
640 \o Borland C++ Builder (Versions 5 and 6)
644 \section2 Typical Runtime Errors
646 \section3 The Server Does Not Respond
648 If the system is unable to start the server (check with the task
649 manager whether the server runs a process), make sure that no DLL
650 the server depends on is missing from the system path (e.g. the Qt
651 DLL!). Use a dependency walker to view all dependencies of the server
654 If the server runs (e.g. the task manager lists a process), see
655 the following section for information on debugging your server.
657 \section3 The Object Cannot Be Created
659 If the server could be built and registered correctly during the build
660 process, but the object cannot be initiliazed e.g. by the OLE/COM Object
661 Viewer application, make sure that no DLL the server depends on is
662 missing from the system path (e.g. the Qt DLL). Use a dependency walker
663 to view all dependencies of the server binary.
665 If the server runs, see the following section for information on
666 debugging your server.
668 \section2 Debugging Runtime Errors
670 To debug an in-process server in Visual Studio, set the server project
671 as the active project, and specify a client "executable for debug
672 session" in the project settings (e.g. use the ActiveX Test Container).
673 You can set breakpoints in your code, and also step into ActiveQt and
674 Qt code if you installed the debug version.
676 To debug an executable server, run the application in a debugger
677 and start with the command line parameter \c -activex. Then start
678 your client and create an instance of your ActiveX control. COM
679 will use the existing process for the next client trying to create
682 \section1 Class Information and Tuning
684 To provide attributes for each COM class, use the Q_CLASSINFO macro, which is part of
685 Qt's meta object system.
693 \o The version of the class (1.0 is default)
696 \o A string describing the class.
700 You must reimplement QAxFactory::classID if not specified.
704 You must reimplement QAxFactory::interfaceID if not specified.
707 \o The event interface ID.
708 No signals are exposed as COM events if not specified.
711 \o The property specified represents the default property of this class.
712 Ie. the default property of a push button would be "text".
715 \o The signal specified respresents the default signal of this class.
716 Ie. the default signal of a push button would be "clicked".
719 \o Object creation requires the specified license key. The key can be
720 empty to require a licensed machine. By default classes are not
721 licensed. Also see the following section.
724 \o Objects expose stock events if value is "yes".
725 See \l QAxFactory::hasStockEvents()
728 \o Objects expose functionality of all super-classes up to and
729 including the class name in value.
730 See \l QAxFactory::exposeToSuperClass()
733 \o If the value is "yes" the class is registered to be "Insertable"
734 and will be listed in OLE 2 containers (ie. Microsoft Office). This
735 attribute is not be set by default.
738 \o If the value is "no" the class does not support aggregation. By
739 default aggregation is supported.
742 \o If the value is "no" the class cannot be created by the client,
743 and is only available through the API of another class (ie. the
744 class is a sub-type).
747 \o If the value is "yes" objects of this class are registered with
748 OLE and accessible from the running object table (ie. clients
749 can connect to an already running instance of this class). This
750 attribute is only supported in out-of-process servers.
753 \o The object can handle data and files of the format specified in the
754 value. The value has the format mime:extension:description. Multiple
755 formats are separated by a semicolon.
758 \o The classname used in the generated IDL and in the registry. This is
759 esp. useful for C++ classes that live in a namespace - by default,
760 ActiveQt just removes the "::" to make the IDL compile.
763 Note that both keys and values are case sensitive.
765 The following declares version 2.0 of a class that exposes only its
766 own API, and is available in the "Insert Objects" dialog of Microsoft
769 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 15
771 \section2 Developing Licensed Components
773 If you develop components you might want to control who is able to instantiate
774 those components. Since the server binary can be shipped to and registered on
775 any client machine it is possible for anybody to use those components in his
778 Licensing components can be done using a variety of techniques, e.g. the code
779 creating the control can provide a license key, or the machine on which the
780 control is supposed to run needs to be licensed.
782 To mark a Qt class as licensed specify a "LicenseKey" using the
785 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 16
787 The key is required to be able to create an instance of \c MyLicensedControl
788 on a machine that is not licensed itself. The licensed developer can now
789 redistributes the server binary with his application, which creates the control
790 using the value of "LicenseKey", while users of the application cannot create
791 the control without the license key.
793 If a single license key for the control is not sufficient (ie. you want
794 differnet developers to receive different license keys) you can specify an
795 empty key to indicate that the control requires a license, and reimplement
796 \l QAxFactory::validateLicenseKey() to verify that a license exists on the
797 system (ie. through a license file).
799 \section2 More Interfaces
801 ActiveX controls provided by ActiveQt servers support a minimal set of COM
802 interfaces to implement the OLE specifications. When the ActiveX class inherits
803 from the QAxBindable class it can also implement additional COM interfaces.
805 Create a new subclass of QAxAggregated and use multiple inheritance
806 to subclass additional COM interface classes.
808 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 17
810 Reimplement the QAxAggregated::queryInterface() function to
811 support the additional COM interfaces.
813 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 18
815 Since \c ISomeCOMInterface is a subclass of \c IUnknown you will
816 have to implement the \c QueryInterface(), \c AddRef(), and \c
817 Release() functions. Use the QAXAGG_IUNKNOWN macro in your
818 class definition to do that. If you implement the \c IUnknown
819 functions manually, delegate the calls to the interface pointer
820 returned by the QAxAggregated::controllingUnknown() function,
823 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 19
825 Do not support the \c IUnknown interface itself in your
826 \l{QAxAggregated::queryInterface()}{queryInterface()}
829 Implement the methods of the COM interfaces, and use QAxAggregated::object()
830 if you need to make calls to the QObject subclass implementing the control.
832 In your QAxBindable subclass, implement
833 QAxBindable::createAggregate() to return a new object of the
834 QAxAggregated subclass.
836 \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 20