source: trunk/doc/src/frameworks-technologies/activeqt-server.qdoc

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 29.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:FDL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in a
14** written agreement between you and Nokia.
15**
16** GNU Free Documentation License
17** Alternatively, this file may be used under the terms of the GNU Free
18** Documentation License version 1.3 as published by the Free Software
19** Foundation and appearing in the file included in the packaging of this
20** file.
21**
22** If you have questions regarding the use of this file, please contact
23** Nokia at qt-info@nokia.com.
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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 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.qdoc 20
837*/
Note: See TracBrowser for help on using the repository browser.