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