1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** Contact: Qt Software Information ([email protected])
|
---|
5 | **
|
---|
6 | ** This file is part of the documentation of the Qt Toolkit.
|
---|
7 | **
|
---|
8 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
9 | ** Commercial Usage
|
---|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
11 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
12 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
13 | ** a written agreement between you and Nokia.
|
---|
14 | **
|
---|
15 | ** GNU Lesser General Public License Usage
|
---|
16 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
17 | ** General Public License version 2.1 as published by the Free Software
|
---|
18 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
19 | ** packaging of this file. Please review the following information to
|
---|
20 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
22 | **
|
---|
23 | ** In addition, as a special exception, Nokia gives you certain
|
---|
24 | ** additional rights. These rights are described in the Nokia Qt LGPL
|
---|
25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
---|
26 | ** package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you are unsure which license is appropriate for your use, please
|
---|
37 | ** contact the sales department at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | /*!
|
---|
43 | \module QAxServer
|
---|
44 | \title QAxServer Module
|
---|
45 | \contentspage Qt's Modules
|
---|
46 | \previouspage QAxContainer
|
---|
47 | \nextpage QtDBus module
|
---|
48 | \ingroup modules
|
---|
49 |
|
---|
50 | \brief The QAxServer module is a Windows-only static library that
|
---|
51 | you can use to turn a standard Qt binary into a COM server.
|
---|
52 |
|
---|
53 | The QAxServer module is part of the \l ActiveQt framework. It
|
---|
54 | consists of three classes:
|
---|
55 |
|
---|
56 | \list
|
---|
57 | \o QAxFactory defines a factory for the creation of COM objects.
|
---|
58 | \o QAxBindable provides an interface between the Qt widget and the
|
---|
59 | COM object.
|
---|
60 | \o QAxAggregated can be subclassed to implement additional COM interfaces.
|
---|
61 | \endlist
|
---|
62 |
|
---|
63 | Some \l{Qt Examples#ActiveQt}{example implementations} of ActiveX
|
---|
64 | controls and COM objects are provided.
|
---|
65 |
|
---|
66 | \sa {ActiveQt Framework}
|
---|
67 |
|
---|
68 | Topics:
|
---|
69 |
|
---|
70 | \tableofcontents
|
---|
71 |
|
---|
72 | \section1 Using the Library
|
---|
73 |
|
---|
74 | To turn a standard Qt application into a COM server using the
|
---|
75 | QAxServer library you must add \c qaxserver as a CONFIG setting
|
---|
76 | in your \c .pro file.
|
---|
77 |
|
---|
78 | An out-of-process executable server is generated from a \c .pro
|
---|
79 | file like this:
|
---|
80 |
|
---|
81 | \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 0
|
---|
82 |
|
---|
83 | To build an in-process server, use a \c .pro file like this:
|
---|
84 | \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 1
|
---|
85 |
|
---|
86 | The files \c qaxserver.rc and \c qaxserver.def are part of the
|
---|
87 | framework and can be used from their usual location (specify a
|
---|
88 | path in the \c .pro file), or copied into the project directory.
|
---|
89 | You can modify these files as long as it includes any file as the
|
---|
90 | type library entry, ie. you can add version information or specify
|
---|
91 | a different toolbox icon.
|
---|
92 |
|
---|
93 | The \c qaxserver configuration will cause the \c qmake tool to add the
|
---|
94 | required build steps to the build system:
|
---|
95 |
|
---|
96 | \list
|
---|
97 | \o Link the binary against \c qaxserver.lib instead of \c qtmain.lib
|
---|
98 | \o Call the \l idc tool to generate an IDL file for the COM server
|
---|
99 | \o Compile the IDL into a type library using the MIDL tool (part of the
|
---|
100 | compiler installation)
|
---|
101 | \o Attach the resulting type library as a binary resource to the server
|
---|
102 | binary (again using the \l idc tool)
|
---|
103 | \o Register the server
|
---|
104 | \endlist
|
---|
105 |
|
---|
106 | Note that the QAxServer build system is not supported on Windows 98/ME
|
---|
107 | (attaching of resources to a binary is not possible there), but a server
|
---|
108 | built on Windows NT/2000/XP will work on previous Windows versions as well.
|
---|
109 |
|
---|
110 | To skip the post-processing step, also set the \c qaxserver_no_postlink
|
---|
111 | configuration.
|
---|
112 |
|
---|
113 | Additionally you can specify a version number using the \c VERSION
|
---|
114 | variable, e.g.
|
---|
115 |
|
---|
116 | \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 2
|
---|
117 |
|
---|
118 | The version number specified will be used as the version of the type
|
---|
119 | library and of the server when registering.
|
---|
120 |
|
---|
121 | \section2 Out-of-Process vs. In-Process
|
---|
122 |
|
---|
123 | Whether your COM server should run as a stand-alone executable
|
---|
124 | or as a shared library in the client process depends mainly on the
|
---|
125 | type of COM objects you want to provide in the server.
|
---|
126 |
|
---|
127 | An executable server has the advantage of being able to run as a
|
---|
128 | stand-alone application, but adds considerable overhead to the
|
---|
129 | communication between the COM client and the COM object. If the
|
---|
130 | control has a programming error only the server process running
|
---|
131 | the control will crash, and the client application will probably
|
---|
132 | continue to run. Not all COM clients support executable servers.
|
---|
133 |
|
---|
134 | An in-process server is usually smaller and has faster startup
|
---|
135 | time. The communication between client and server is done directly
|
---|
136 | through virtual function calls and does not introduce the overhead
|
---|
137 | required for remote procedure calls. However, if the server crashes the
|
---|
138 | client application is likely to crash as well, and not every
|
---|
139 | functionality is available for in-process servers (i.e. register in
|
---|
140 | the COM's running-object-table).
|
---|
141 |
|
---|
142 | Both server types can use Qt either as a shared library, or statically
|
---|
143 | linked into the server binary.
|
---|
144 |
|
---|
145 | \section2 Typical Errors During the Post-Build Steps
|
---|
146 |
|
---|
147 | For the ActiveQt specific post-processing steps to work the
|
---|
148 | server has to meet some requirements:
|
---|
149 |
|
---|
150 | \list
|
---|
151 | \o All controls exposed can be created with nothing but a QApplication
|
---|
152 | instance being present
|
---|
153 | \o The initial linking of the server includes a temporary type
|
---|
154 | library resource
|
---|
155 | \o All dependencies required to run the server are in the system path
|
---|
156 | (or in the path used by the calling environment; note that Visual
|
---|
157 | Studio has its own set of environment variables listed in the
|
---|
158 | Tools|Options|Directories dialog).
|
---|
159 | \endlist
|
---|
160 |
|
---|
161 | If those requirements are not met one ore more of the following
|
---|
162 | errors are likely to occur:
|
---|
163 |
|
---|
164 | \section3 The Server Executable Crashes
|
---|
165 |
|
---|
166 | To generate the IDL the widgets exposed as ActiveX controls need to
|
---|
167 | be instantiated (the constructor is called). At this point, nothing
|
---|
168 | else but a QApplication object exists. Your widget constructor must
|
---|
169 | not rely on any other objects to be created, e.g. it should check for
|
---|
170 | null-pointers.
|
---|
171 |
|
---|
172 | To debug your server run it with -dumpidl outputfile and check where
|
---|
173 | it crashes.
|
---|
174 |
|
---|
175 | Note that no functions of the control are called.
|
---|
176 |
|
---|
177 | \section3 The Server Executable Is Not a Valid Win32 Application
|
---|
178 |
|
---|
179 | Attaching the type library corrupted the server binary. This is a
|
---|
180 | bug in Windows and happens only with release builds.
|
---|
181 |
|
---|
182 | The first linking step has to link a dummy type library into the
|
---|
183 | executable that can later be replaced by idc. Add a resource file
|
---|
184 | with a type library to your project as demonstrated in the examples.
|
---|
185 |
|
---|
186 | \section3 "Unable to locate DLL"
|
---|
187 |
|
---|
188 | The build system needs to run the server executable to generate
|
---|
189 | the interface definition, and to register the server. If a dynamic
|
---|
190 | link library the server links against is not in the path this
|
---|
191 | might fail (e.g. Visual Studio calls the server using the
|
---|
192 | enivronment settings specified in the "Directories" option). Make
|
---|
193 | sure that all DLLs required by your server are located in a
|
---|
194 | directory that is listed in the path as printed in the error
|
---|
195 | message box.
|
---|
196 |
|
---|
197 | \section3 "Cannot open file ..."
|
---|
198 |
|
---|
199 | The ActiveX server could not shut down properly when the last
|
---|
200 | client stopped using it. It usually takes about two seconds for
|
---|
201 | the application to terminate, but you might have to use the task
|
---|
202 | manager to kill the process (e.g. when a client doesn't release
|
---|
203 | the controls properly).
|
---|
204 |
|
---|
205 | \section1 Implementing Controls
|
---|
206 |
|
---|
207 | To implement a COM object with Qt, create a subclass of QObject
|
---|
208 | or any existing QObject subclass. If the class is a subclass of QWidget,
|
---|
209 | the COM object will be an ActiveX control.
|
---|
210 |
|
---|
211 | \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 3
|
---|
212 |
|
---|
213 | The Q_OBJECT macro is required to provide the meta object information
|
---|
214 | about the widget to the ActiveQt framework.
|
---|
215 |
|
---|
216 | \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 4
|
---|
217 |
|
---|
218 | Use the Q_CLASSINFO() macro to specify the COM identifiers for the COM
|
---|
219 | object. \c ClassID and \c InterfaceID are required, while \c EventsID is
|
---|
220 | only necessary when your object has signals. To generate these identifiers,
|
---|
221 | use system tools like \c uuidgen or \c guidgen.
|
---|
222 |
|
---|
223 | You can specify additional attributes for each of your classes; see
|
---|
224 | \l{Class Information and Tuning} for details.
|
---|
225 |
|
---|
226 | \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 5
|
---|
227 |
|
---|
228 | Use the Q_PROPERTY() macro to declare properties for the ActiveX control.
|
---|
229 |
|
---|
230 | Declare a standard constructor taking a parent object, and functions,
|
---|
231 | signals and slots like for any QObject subclass.
|
---|
232 | \footnote
|
---|
233 | If a standard constructor is not present the compiler will issue
|
---|
234 | an error "no overloaded function takes 2 parameters" when using
|
---|
235 | the default factory through the QAXFACTORY_DEFAULT() macro. If you
|
---|
236 | cannot provide a standard constructor you must implement a
|
---|
237 | QAxFactory custom factory and call the constructor you have in
|
---|
238 | your implementation of QAxFactory::create.
|
---|
239 | \endfootnote
|
---|
240 |
|
---|
241 | \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 6
|
---|
242 |
|
---|
243 | The ActiveQt framework will expose properties and public slots as ActiveX
|
---|
244 | properties and methods, and signals as ActiveX events, and convert between
|
---|
245 | the Qt data types and the equivalent COM data types.
|
---|
246 |
|
---|
247 | \section2 Data Types
|
---|
248 |
|
---|
249 | The Qt data types that are supported for properties are:
|
---|
250 |
|
---|
251 | \table
|
---|
252 | \header
|
---|
253 | \o Qt data type
|
---|
254 | \o COM property
|
---|
255 | \row
|
---|
256 | \o bool
|
---|
257 | \o VARIANT_BOOL
|
---|
258 | \row
|
---|
259 | \o QString
|
---|
260 | \o BSTR
|
---|
261 | \row
|
---|
262 | \o int
|
---|
263 | \o int
|
---|
264 | \row
|
---|
265 | \o uint
|
---|
266 | \o unsigned int
|
---|
267 | \row
|
---|
268 | \o double
|
---|
269 | \o double
|
---|
270 | \row
|
---|
271 | \o \l qlonglong
|
---|
272 | \o CY
|
---|
273 | \row
|
---|
274 | \o \l qulonglong
|
---|
275 | \o CY
|
---|
276 | \row
|
---|
277 | \o QColor
|
---|
278 | \o OLE_COLOR
|
---|
279 | \row
|
---|
280 | \o QDate
|
---|
281 | \o DATE
|
---|
282 | \row
|
---|
283 | \o QDateTime
|
---|
284 | \o DATE
|
---|
285 | \row
|
---|
286 | \o QTime
|
---|
287 | \o DATE
|
---|
288 | \row
|
---|
289 | \o QFont
|
---|
290 | \o IFontDisp*
|
---|
291 | \row
|
---|
292 | \o QPixmap
|
---|
293 | \o IPictureDisp*
|
---|
294 | \footnote
|
---|
295 | COM cannot marshal IPictureDisp accross process boundaries,
|
---|
296 | so QPixmap properties cannot be called for out-of-process servers. You
|
---|
297 | can however marshal the image data via e.g. temporary files. See the
|
---|
298 | Microsoft
|
---|
299 | \link http://support.microsoft.com/default.aspx?scid=kb;[LN];Q150034 KB article
|
---|
300 | Q150034 \endlink for more information.
|
---|
301 | \endfootnote
|
---|
302 | \row
|
---|
303 | \o QVariant
|
---|
304 | \o VARIANT
|
---|
305 | \row
|
---|
306 | \o QVariantList (same as QList\<QVariant\>)
|
---|
307 | \o SAFEARRAY(VARIANT)
|
---|
308 | \row
|
---|
309 | \o QStringList
|
---|
310 | \o SAFEARRAY(BSTR)
|
---|
311 | \row
|
---|
312 | \o QByteArray
|
---|
313 | \o SAFEARRAY(BYTE)
|
---|
314 | \row
|
---|
315 | \o QRect
|
---|
316 | \o User defined type
|
---|
317 | \row
|
---|
318 | \o QSize
|
---|
319 | \o User defined type
|
---|
320 | \row
|
---|
321 | \o QPoint
|
---|
322 | \o User defined type
|
---|
323 | \endtable
|
---|
324 |
|
---|
325 | The Qt data types that are supported for parameters in signals and
|
---|
326 | slots are:
|
---|
327 | \table
|
---|
328 | \header
|
---|
329 | \o Qt data type
|
---|
330 | \o COM parameter
|
---|
331 | \row
|
---|
332 | \o bool
|
---|
333 | \o [in] VARIANT_BOOL
|
---|
334 | \row
|
---|
335 | \o bool&
|
---|
336 | \o [in, out] VARIANT_BOOL*
|
---|
337 | \row
|
---|
338 | \o QString, const QString&
|
---|
339 | \o [in] BSTR
|
---|
340 | \row
|
---|
341 | \o QString&
|
---|
342 | \o [in, out] BSTR*
|
---|
343 | \row
|
---|
344 | \o QString&
|
---|
345 | \o [in, out] BSTR*
|
---|
346 | \row
|
---|
347 | \o int
|
---|
348 | \o [in] int
|
---|
349 | \row
|
---|
350 | \o int&
|
---|
351 | \o [in,out] int
|
---|
352 | \row
|
---|
353 | \o uint
|
---|
354 | \o [in] unsigned int
|
---|
355 | \row
|
---|
356 | \o uint&
|
---|
357 | \o [in, out] unsigned int*
|
---|
358 | \row
|
---|
359 | \o double
|
---|
360 | \o [in] double
|
---|
361 | \row
|
---|
362 | \o double&
|
---|
363 | \o [in, out] double*
|
---|
364 | \row
|
---|
365 | \o QColor, const QColor&
|
---|
366 | \o [in] OLE_COLOR
|
---|
367 | \row
|
---|
368 | \o QColor&
|
---|
369 | \o [in, out] OLE_COLOR*
|
---|
370 | \row
|
---|
371 | \o QDate, const QDate&
|
---|
372 | \o [in] DATE
|
---|
373 | \row
|
---|
374 | \o QDate&
|
---|
375 | \o [in, out] DATE*
|
---|
376 | \row
|
---|
377 | \o QDateTime, const QDateTime&
|
---|
378 | \o [in] DATE
|
---|
379 | \row
|
---|
380 | \o QDateTime&
|
---|
381 | \o [in, out] DATE*
|
---|
382 | \row
|
---|
383 | \o QFont, const QFont&
|
---|
384 | \o [in] IFontDisp*
|
---|
385 | \row
|
---|
386 | \o QFont&
|
---|
387 | \o [in, out] IFontDisp**
|
---|
388 | \row
|
---|
389 | \o QPixmap, const QPixmap&
|
---|
390 | \o [in] IPictureDisp*
|
---|
391 | \row
|
---|
392 | \o QPixmap&
|
---|
393 | \o [in, out] IPictureDisp**
|
---|
394 | \row
|
---|
395 | \o QList\<QVariant\>, const QList\<QVariant\>&
|
---|
396 | \o [in] SAFEARRAY(VARIANT)
|
---|
397 | \row
|
---|
398 | \o QList\<QVariant\>&
|
---|
399 | \o [in, out] SAFEARRAY(VARIANT)*
|
---|
400 | \row
|
---|
401 | \o QStringList, const QStringList&
|
---|
402 | \o [in] SAFEARRAY(BSTR)
|
---|
403 | \row
|
---|
404 | \o QStringList&
|
---|
405 | \o [in, out] SAFEARRAY(BSTR)*
|
---|
406 | \row
|
---|
407 | \o QByteArray, const QByteArray&
|
---|
408 | \o [in] SAFEARRAY(BYTE)
|
---|
409 | \row
|
---|
410 | \o QByteArray&
|
---|
411 | \o [in, out] SAFEARRAY(BYTE)*
|
---|
412 | \row
|
---|
413 | \o QObject*
|
---|
414 | \o [in] IDispatch*
|
---|
415 | \row
|
---|
416 | \o QRect&
|
---|
417 | \footnote
|
---|
418 | OLE needs to marshal user defined types by reference (ByRef), and cannot
|
---|
419 | marshal them by value (ByVal). This is why const-references and object
|
---|
420 | parameters are not supported for QRect, QSize and QPoint. Also note that
|
---|
421 | servers with this datatype require Windows 98 or DCOM 1.2 to be installed.
|
---|
422 | \endfootnote
|
---|
423 | \o [in, out] struct QRect (user defined)
|
---|
424 | \row
|
---|
425 | \o QSize&
|
---|
426 | \o [in, out] struct QSize (user defined)
|
---|
427 | \row
|
---|
428 | \o QPoint&
|
---|
429 | \o [in, out] struct QPoint (user defined)
|
---|
430 | \endtable
|
---|
431 |
|
---|
432 | Also supported are exported enums and flags (see Q_ENUMS() and
|
---|
433 | Q_FLAGS()). The in-parameter types are also supported as
|
---|
434 | return values.
|
---|
435 |
|
---|
436 | Properties and signals/slots that have parameters using any other
|
---|
437 | data types are ignored by the ActiveQt framework.
|
---|
438 |
|
---|
439 | \section2 Sub-Objects
|
---|
440 |
|
---|
441 | COM objects can have multiple sub-objects that can represent a sub element
|
---|
442 | of the COM object. A COM object representing a multi-document spread sheet
|
---|
443 | application can for example provide one sub-object for each spread sheet.
|
---|
444 |
|
---|
445 | Any QObject subclass can be used as the type for a sub object in ActiveX, as
|
---|
446 | long as it is known to the QAxFactory. Then the type can be used in properties,
|
---|
447 | or as the return type or paramter of a slot.
|
---|
448 |
|
---|
449 | \section2 Property Notification
|
---|
450 |
|
---|
451 | To make the properties bindable for the ActiveX client, use multiple
|
---|
452 | inheritance from the QAxBindable class:
|
---|
453 |
|
---|
454 | \snippet doc/src/snippets/code/doc_src_qaxserver.qdoc 7
|
---|
455 |
|
---|
456 | When implementing the property write functions, use the
|
---|
457 | QAxBindable class's requestPropertyChange() and propertyChanged()
|
---|
458 | functions to allow ActiveX clients to bind to the control
|
---|
459 | properties.
|
---|
460 | \footnote
|
---|
461 | This is not required, but gives the client more control over
|
---|
462 | the ActiveX control.
|
---|
463 | \endfootnote
|
---|
464 |
|
---|
465 | \section1 Serving Controls
|
---|
|
---|