Update copyright headers
[qt:qt.git] / doc / src / frameworks-technologies / activeqt-server.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
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.
16 **
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.
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \page activeqt-server.html
30     \title Building ActiveX servers in Qt
31     \ingroup qt-activex
32
33     \brief A Windows-only static library for turning a Qt binary into a COM server.
34
35     The QAxServer module is part of the \l ActiveQt framework. It
36     consists of three classes:
37
38     \list
39     \o QAxFactory defines a factory for the creation of COM objects.
40     \o QAxBindable provides an interface between the Qt widget and the 
41        COM object.
42     \o QAxAggregated can be subclassed to implement additional COM interfaces.
43     \endlist
44
45     Some \l{ActiveQt Examples}{example implementations} of ActiveX
46     controls and COM objects are provided.
47
48     \sa {ActiveQt Framework}
49
50     Topics:
51
52     \tableofcontents
53
54     \section1 Using the Library
55
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
58     in your \c .pro file.
59
60     An out-of-process executable server is generated from a \c .pro
61     file like this:
62
63     \snippet doc/src/snippets/code/doc_src_qaxserver.pro 0
64
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
67
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.
74
75     The \c qaxserver configuration will cause the \c qmake tool to add the 
76     required build steps to the build system:
77
78     \list
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
86     \endlist
87
88     To skip the post-processing step, also set the \c qaxserver_no_postlink
89     configuration.
90
91     Additionally you can specify a version number using the \c VERSION
92     variable, e.g.
93
94     \snippet doc/src/snippets/code/doc_src_qaxserver.pro 2
95
96     The version number specified will be used as the version of the type
97     library and of the server when registering.
98
99     \section2 Out-of-Process vs. In-Process
100
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. 
104
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.
111
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).
119
120     Both server types can use Qt either as a shared library, or statically
121     linked into the server binary.
122
123     \section2 Typical Errors During the Post-Build Steps
124
125     For the ActiveQt specific post-processing steps to work the 
126     server has to meet some requirements:
127
128     \list
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 
132     library resource
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).
137     \endlist
138
139     If those requirements are not met one ore more of the following 
140     errors are likely to occur:
141
142     \section3 The Server Executable Crashes
143
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
148     null-pointers.
149
150     To debug your server run it with -dumpidl outputfile and check where
151     it crashes.
152
153     Note that no functions of the control are called.
154
155     \section3 The Server Executable Is Not a Valid Win32 Application
156
157     Attaching the type library corrupted the server binary. This is a
158     bug in Windows and happens only with release builds.
159
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.
163
164     \section3 "Unable to locate DLL"
165
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
173     message box.
174
175     \section3 "Cannot open file ..."
176
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).
182
183     \section1 Implementing Controls
184
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.
188
189     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 3
190
191     The Q_OBJECT macro is required to provide the meta object information
192     about the widget to the ActiveQt framework.
193
194     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 4
195
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.
200
201     You can specify additional attributes for each of your classes; see 
202     \l{Class Information and Tuning} for details.
203
204     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 5
205
206     Use the Q_PROPERTY() macro to declare properties for the ActiveX control.
207
208     Declare a standard constructor taking a parent object, and functions, 
209     signals and slots like for any QObject subclass.
210     \footnote
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.
217     \endfootnote
218
219     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 6
220
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.
224
225     \section2 Data Types
226
227     The Qt data types that are supported for properties are:
228
229     \table
230     \header
231     \o Qt data type
232     \o COM property
233     \row
234     \o bool
235     \o VARIANT_BOOL
236     \row
237     \o QString
238     \o BSTR
239     \row
240     \o int
241     \o int
242     \row
243     \o uint
244     \o unsigned int
245     \row
246     \o double
247     \o double
248     \row
249     \o \l qlonglong
250     \o CY
251     \row
252     \o \l qulonglong
253     \o CY
254     \row
255     \o QColor
256     \o OLE_COLOR
257     \row
258     \o QDate
259     \o DATE
260     \row
261     \o QDateTime
262     \o DATE
263     \row
264     \o QTime
265     \o DATE
266     \row
267     \o QFont
268     \o IFontDisp*
269     \row
270     \o QPixmap
271     \o IPictureDisp*
272     \footnote
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
276     Microsoft 
277     \link http://support.microsoft.com/default.aspx?scid=kb;[LN];Q150034 KB article 
278     Q150034 \endlink for more information.
279     \endfootnote
280     \row
281     \o QVariant
282     \o VARIANT
283     \row
284     \o QVariantList (same as QList\<QVariant\>)
285     \o SAFEARRAY(VARIANT)
286     \row
287     \o QStringList
288     \o SAFEARRAY(BSTR)
289     \row
290     \o QByteArray
291     \o SAFEARRAY(BYTE)
292     \row
293     \o QRect
294     \o User defined type
295     \row
296     \o QSize
297     \o User defined type
298     \row
299     \o QPoint
300     \o User defined type
301     \endtable
302
303     The Qt data types that are supported for parameters in signals and
304     slots are:
305     \table
306     \header
307     \o Qt data type
308     \o COM parameter
309     \row
310     \o bool
311     \o [in] VARIANT_BOOL
312     \row
313     \o bool&
314     \o [in, out] VARIANT_BOOL*
315     \row
316     \o QString, const QString&
317     \o [in] BSTR
318     \row
319     \o QString&
320     \o [in, out] BSTR*
321     \row
322     \o QString&
323     \o [in, out] BSTR*
324     \row
325     \o int
326     \o [in] int
327     \row
328     \o int&
329     \o [in,out] int
330     \row
331     \o uint
332     \o [in] unsigned int
333     \row
334     \o uint&
335     \o [in, out] unsigned int*
336     \row
337     \o double
338     \o [in] double
339     \row
340     \o double&
341     \o [in, out] double*
342     \row
343     \o QColor, const QColor&
344     \o [in] OLE_COLOR
345     \row
346     \o QColor&
347     \o [in, out] OLE_COLOR*
348     \row
349     \o QDate, const QDate&
350     \o [in] DATE
351     \row
352     \o QDate&
353     \o [in, out] DATE*
354     \row
355     \o QDateTime, const QDateTime&
356     \o [in] DATE
357     \row
358     \o QDateTime&
359     \o [in, out] DATE*
360     \row
361     \o QFont, const QFont&
362     \o [in] IFontDisp*
363     \row
364     \o QFont&
365     \o [in, out] IFontDisp**
366     \row
367     \o QPixmap, const QPixmap&
368     \o [in] IPictureDisp*
369     \row
370     \o QPixmap&
371     \o [in, out] IPictureDisp**
372     \row
373     \o QList\<QVariant\>, const QList\<QVariant\>&
374     \o [in] SAFEARRAY(VARIANT)
375     \row
376     \o QList\<QVariant\>&
377     \o [in, out] SAFEARRAY(VARIANT)*
378     \row
379     \o QStringList, const QStringList&
380     \o [in] SAFEARRAY(BSTR)
381     \row
382     \o QStringList&
383     \o [in, out] SAFEARRAY(BSTR)*
384     \row
385     \o QByteArray, const QByteArray&
386     \o [in] SAFEARRAY(BYTE)
387     \row
388     \o QByteArray&
389     \o [in, out] SAFEARRAY(BYTE)*
390     \row
391     \o QObject*
392     \o [in] IDispatch*
393     \row
394     \o QRect&
395     \footnote
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.
399     \endfootnote
400     \o [in, out] struct QRect (user defined)
401     \row
402     \o QSize&
403     \o [in, out] struct QSize (user defined)
404     \row
405     \o QPoint&
406     \o [in, out] struct QPoint (user defined)
407     \endtable
408
409     Also supported are exported enums and flags (see Q_ENUMS() and
410     Q_FLAGS()). The in-parameter types are also supported as
411     return values.
412
413     Properties and signals/slots that have parameters using any other
414     data types are ignored by the ActiveQt framework.
415
416     \section2 Sub-Objects
417
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.
421
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.
425
426     \section2 Property Notification
427
428     To make the properties bindable for the ActiveX client, use multiple
429     inheritance from the QAxBindable class:
430
431     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 7
432
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
436     properties. 
437     \footnote 
438     This is not required, but gives the client more control over 
439     the ActiveX control.
440     \endfootnote
441
442     \section1 Serving Controls
443
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 
450     by the control.
451
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
454     of macros:
455
456     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 8
457
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.
461
462     The \link QAxFactory QAxFactory class documentation \endlink explains 
463     how to use this macro, and how to implement and use custom factories.
464
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:
472
473     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 9
474
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().
478
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.
484
485     If the ActiveX server is an executable, the following command line
486     options are supported:
487     \table
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
494     \endtable
495
496     In-process servers can be registered using the \c regsvr32 tool available
497     on all Windows systems.
498
499     \section2 Typical Compile-Time Problems
500
501     The compiler/linker errors listed are based on those issued by the 
502     Microsoft Visual C++ 6.0 compiler.
503
504     \section3 "No overloaded function takes 2 parameters"
505
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.
510
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
514
515     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 10
516
517     for your factory class.
518
519     \section3 "Syntax error: bad suffix on number"
520
521     The unique identifiers have not been passed as strings into the 
522     QAXFACTORY_EXPORT() or QAXFACTORY_DEFAULT() macro.
523
524     \section3 "Unresolved external symbol _ucm_instantiate"
525
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.
530
531     \section3 "_ucm_initialize already defined in ..."
532
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
538     controls.
539
540     \section2 Distributing QAxServer Binaries
541
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).
546
547     \section3 Installing Stand-Alone Servers
548
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
553     ActiveX clients.
554
555     \section3 Installing In-Process Servers
556
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
561     call the function:
562
563     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 11
564
565     \section3 Distributing Servers over the Internet
566
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.
570
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.
575
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:
580
581     \snippet examples/activeqt/simple/simple.inf 0
582
583     The CABARC tool from Microsoft can easily generate CAB archives:
584
585     \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 12
586
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
590     with the archive.
591
592     \section1 Using the Controls
593
594     To use the ActiveX controls, e.g. to embed them in a web page, use
595     the \c <object> HTML tag. 
596
597     \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 13
598
599     To initialize the control's properties, use
600
601     \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 14
602
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
606     controls.
607
608     \section2 Supported and Unsupported ActiveX Clients
609
610     The following is largly based on our own experiements with ActiveX
611     controls and client applications, and is by no means complete.
612
613     \section3 Supported Clients
614
615     These standard applications work with ActiveX controls developed with 
616     ActiveQt. Note that some clients support only in-process controls.
617
618     \list
619     \o Internet Explorer
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
627     \endlist
628
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.
633
634     \section3 Unsupported Clients
635
636     We have not managed to make ActiveQt based COM objects work with the
637     following client applications.
638
639     \list
640     \o Borland C++ Builder (Versions 5 and 6)
641     \o Borland Delphi
642     \endlist
643
644     \section2 Typical Runtime Errors
645
646     \section3 The Server Does Not Respond
647
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 
652     binary.
653
654     If the server runs (e.g. the task manager lists a process), see
655     the following section for information on debugging your server.
656
657     \section3 The Object Cannot Be Created
658
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.
664
665     If the server runs, see the following section for information on
666     debugging your server.
667
668     \section2 Debugging Runtime Errors
669
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.
675
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 
680     an ActiveX control.
681
682     \section1 Class Information and Tuning
683
684     To provide attributes for each COM class, use the Q_CLASSINFO macro, which is part of
685     Qt's meta object system.
686
687     \table
688     \header
689     \o Key
690     \o Meaning of value
691     \row
692     \o Version
693     \o The version of the class (1.0 is default)
694     \row
695     \o Description
696     \o A string describing the class.
697     \row
698     \o ClassID
699     \o The class ID.
700        You must reimplement QAxFactory::classID if not specified.
701     \row
702     \o InterfaceID
703     \o The interface ID. 
704        You must reimplement QAxFactory::interfaceID if not specified.
705     \row
706     \o EventsID
707     \o The event interface ID.
708        No signals are exposed as COM events if not specified.
709     \row
710     \o DefaultProperty
711     \o The property specified represents the default property of this class.
712        Ie. the default property of a push button would be "text".
713     \row
714     \o DefaultSignal
715     \o The signal specified respresents the default signal of this class.
716        Ie. the default signal of a push button would be "clicked".
717     \row
718     \o LicenseKey
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.
722     \row
723     \o StockEvents
724     \o Objects expose stock events if value is "yes".
725        See \l QAxFactory::hasStockEvents()
726     \row
727     \o ToSuperClass
728     \o Objects expose functionality of all super-classes up to and
729        including the class name in value.
730        See \l QAxFactory::exposeToSuperClass()
731     \row
732     \o Insertable
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.
736     \row
737     \o Aggregatable
738     \o If the value is "no" the class does not support aggregation. By 
739        default aggregation is supported.
740     \row
741     \o Creatable
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).
745     \row
746     \o RegisterObject
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.
751     \row
752     \o MIME
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.
756     \row
757     \o CoClassAlias
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.
761     \endtable
762
763     Note that both keys and values are case sensitive.
764
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
767     Office applications.
768
769     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 15
770
771     \section2 Developing Licensed Components
772
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 
776     own software.
777
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.
781
782     To mark a Qt class as licensed specify a "LicenseKey" using the
783     Q_CLASSINFO() macro.
784
785     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 16
786
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.
792
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).
798
799     \section2 More Interfaces
800
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.
804
805     Create a new subclass of QAxAggregated and use multiple inheritance
806     to subclass additional COM interface classes. 
807
808     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 17
809
810     Reimplement the QAxAggregated::queryInterface() function to
811     support the additional COM interfaces.
812
813     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 18
814
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,
821     e.g.
822
823     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 19
824
825     Do not support the \c IUnknown interface itself in your
826     \l{QAxAggregated::queryInterface()}{queryInterface()}
827     implementation.
828
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.
831
832     In your QAxBindable subclass, implement
833     QAxBindable::createAggregate() to return a new object of the
834     QAxAggregated subclass.
835
836     \snippet doc/src/snippets/code/doc_src_qaxserver.cpp 20
837 */