source: trunk/doc/html/qaxserver.html@ 190

Last change on this file since 190 was 190, checked in by rudi, 14 years ago

reference documentation added

File size: 43.3 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/extensions/activeqt/doc/control.doc:1 -->
3<html>
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
6<title>The QAxServer Module</title>
7<style type="text/css"><!--
8fn { margin-left: 1cm; text-indent: -1cm; }
9a:link { color: #004faf; text-decoration: none }
10a:visited { color: #672967; text-decoration: none }
11body { background: #ffffff; color: black; }
12--></style>
13</head>
14<body>
15
16<table border="0" cellpadding="0" cellspacing="0" width="100%">
17<tr bgcolor="#E5E5E5">
18<td valign=center>
19 <a href="index.html">
20<font color="#004faf">Home</font></a>
21 | <a href="classes.html">
22<font color="#004faf">All&nbsp;Classes</font></a>
23 | <a href="mainclasses.html">
24<font color="#004faf">Main&nbsp;Classes</font></a>
25 | <a href="annotated.html">
26<font color="#004faf">Annotated</font></a>
27 | <a href="groups.html">
28<font color="#004faf">Grouped&nbsp;Classes</font></a>
29 | <a href="functions.html">
30<font color="#004faf">Functions</font></a>
31</td>
32<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>The QAxServer Module</h1>
33
34
35<p>
36<p> <!-- toc -->
37<ul>
38<li><a href="#1"> Introduction
39</a>
40<li><a href="#2"> Building the library
41</a>
42<li><a href="#3"> Using the library
43</a>
44<ul>
45<li><a href="#3-1"> Out-of-process vs. In-process
46</a>
47</ul>
48<li><a href="#4"> The QAxServer build system
49</a>
50<ul>
51<li><a href="#4-1"> Typical build problems
52</a>
53<ul>
54<li><a href="#4-1-1"> Compiler errors
55</a>
56<ul>
57<li><a href="#4-1-1-1"> "No overloaded function takes 2 parameters"
58</a>
59<li><a href="#4-1-1-2"> "syntax error: bad suffix on number"
60</a>
61</ul>
62<li><a href="#4-1-2"> Linker errors
63</a>
64<ul>
65<li><a href="#4-1-2-1"> "unresolved external symbol _ucm_instantiate"
66</a>
67<li><a href="#4-1-2-2"> "_ucm_initialize already defined in ..."
68</a>
69<li><a href="#4-1-2-3"> "cannot open file ... "
70</a>
71</ul>
72<li><a href="#4-1-3"> Postprocessing and runtime errors
73</a>
74<ul>
75<li><a href="#4-1-3-1"> The server executable crashes
76</a>
77<li><a href="#4-1-3-2"> The server executable is not a valid Win32 application
78</a>
79<li><a href="#4-1-3-3"> "Unable to Locate DLL"
80</a>
81<li><a href="#4-1-3-4"> The Server does not respond
82</a>
83<li><a href="#4-1-3-5"> The Object cannot be created
84</a>
85</ul>
86</ul>
87<li><a href="#4-2"> Debugging runtime errors
88</a>
89</ul>
90<li><a href="#5"> Implementing Controls
91</a>
92<ul>
93<li><a href="#5-1"> Data Types
94</a>
95<li><a href="#5-2"> Sub-Objects
96</a>
97<li><a href="#5-3"> Property Notification
98</a>
99</ul>
100<li><a href="#6"> Serving Controls
101</a>
102<ul>
103<li><a href="#6-1"> Distributing QAxServer binaries
104</a>
105<ul>
106<li><a href="#6-1-1"> Installing stand-alone Servers
107</a>
108<li><a href="#6-1-2"> Installing In-process Servers
109</a>
110<li><a href="#6-1-3"> Distributing Servers over the Internet
111</a>
112</ul>
113</ul>
114<li><a href="#7"> Using the Controls
115</a>
116<ul>
117<li><a href="#7-1"> Supported and Unsupported ActiveX clients
118</a>
119<ul>
120<li><a href="#7-1-1"> Supported Clients
121</a>
122<li><a href="#7-1-2"> Unsupported Clients
123</a>
124</ul>
125</ul>
126<li><a href="#8"> Enhanced features
127</a>
128<ul>
129<li><a href="#8-1"> Fewer methods and properties
130</a>
131<li><a href="#8-2"> Class Information and Tuning
132</a>
133<li><a href="#8-3"> Developing licensed components
134</a>
135<li><a href="#8-4"> More Interfaces
136</a>
137</ul>
138</ul>
139<!-- endtoc -->
140
141<p> <h2> Introduction
142</h2>
143<a name="1"></a><p> The QAxServer module provides a static library implementing the
144functions required to turn a standard Qt binary into an ActiveX
145control server.
146<p> This module is part of the <a href="activeqt.html">ActiveQt
147 framework</a>. (To incorporate ActiveX controls in a Qt
148application see the <a href="qaxcontainer.html">QAxContainer
149 module</a>.)
150<p> The module consists of three classes
151<ul>
152<li> <a href="qaxfactory.html">QAxFactory</a> defines a factory for the creation of ActiveX components.
153<li> <a href="qaxbindable.html">QAxBindable</a> provides an interface between the Qt widget and the
154ActiveX control.
155<li> <a href="qaxaggregated.html">QAxAggregated</a> can be subclassed to implement additional COM interfaces.
156</ul>
157<p> Some <a href="qaxserver-examples.html">example implementations</a>
158of ActiveX controls are provided.
159<p> <h2> Building the library
160</h2>
161<a name="2"></a><p> In the <tt>activeqt</tt> directory (usually <tt>QTDIR/extensions/activeqt</tt>)
162enter the <tt>control</tt> subdirectory and run <tt>qmake</tt> to generate the
163makefile, and use the make tool (<tt>nmake</tt> for VC++, <tt>make</tt> for Borland)
164to build the library. The library <tt>qaxserver.lib</tt> will be linked into
165<tt>QTDIR/lib</tt>.
166<p> <h2> Using the library
167</h2>
168<a name="3"></a><p> To turn a standard Qt application into an ActiveX server using the
169QAxServer library you must add <tt>activeqt</tt> as a CONFIG setting
170in your <tt>.pro</tt> file.
171<p> An out-of-process executable server is generated from a <tt>.pro</tt>
172file like this:
173<pre>
174 TEMPLATE = app
175 CONFIG += qt activeqt
176
177 RC_FILE = qaxserver.rc
178 ...
179 </pre>
180
181<p> To build an in-process server, use a <tt>.pro</tt> file like this:
182<pre>
183 TEMPLATE = lib
184 CONFIG += qt activeqt dll
185
186 DEF_FILE = qaxserver.def
187 RC_FILE = qaxserver.rc
188 ...
189 </pre>
190
191<p> The files <tt>qaxserver.rc</tt> and <tt>qaxserver.def</tt> are part of the
192framework and can be used from their usual location (specify a
193path in the <tt>.pro</tt> file), or copied into the project directory.
194You can modify these files as long as it includes any file as the
195type library entry, ie. you can add version information or use a
196different toolbox icon.
197<p> The <tt>activeqt</tt> configuration will cause the <tt>qmake</tt> tool to add the
198required build steps to the build system:
199<ul>
200<li> link the binary against <tt>qaxserver.lib</tt>
201<li> generate an interface definition and link the type library into
202the binary
203<li> register the server
204</ul>
205<p> Additionally you can specify a version number using the <tt>VERSION</tt>
206variable, e.g.
207<pre>
208 TEMPLATE = lib
209 VERSION = 2.5
210 ...
211 </pre>
212
213The version number specified will be used as the version of the type
214library and of the server when registering.
215<p> <h3> Out-of-process vs. In-process
216</h3>
217<a name="3-1"></a><p> Whether your ActiveX server should run as a stand-alone executable
218or as a shared library in the client process depends mainly on the
219type of controls you want to provide in the server.
220<p> An executable server has the advantage of being able to run as a
221stand-alone application, but adds considerable overhead to the
222communication between the ActiveX client and the control. If the
223control has a programming error only the server process running
224the control will crash, and the client application will probably
225continue to run.
226<p> An in-process server is usually smaller and has faster startup
227time. The communication between client and server is done directly
228through virtual function calls and does not introduce the overhead
229required for remote procedure calls. But if the server crashes the
230client application is likely to crash as well.
231<p> Both server types can use Qt either as a shared library, or
232statically linked into the server binary.
233<p> <h2> The QAxServer build system
234</h2>
235<a name="4"></a><p> To be able to build ActiveX controls with Qt, the build system
236must be extended to include some additional build steps that are
237used when the <tt>.pro</tt> file includes <tt>activeqt</tt> in the <tt>CONFIG</tt>
238settings. The resulting makefile will:
239<p> <ul>
240<li> Link the executable against <tt>qaxserver.lib</tt> instead of <tt>qtmain.lib</tt>
241<li> Call the resulting executable with the <tt>-dumpidl</tt> parameter to
242generate an IDL description of the ActiveX controls provided by
243the server.
244<li> Compile the IDL into a type library using the MIDL tool
245<li> Attach the resulting type library as a binary resource to the server
246executable
247</ul>
248<p> Attaching resources to an executable is not supported by
249Windows&nbsp;95/98/ME, but a server built on
250Windows&nbsp;NT/2000/XP will work on those versions.
251<p> <h3> Typical build problems
252</h3>
253<a name="4-1"></a><p> The compiler/linker errors listed are based on those issued by the
254Microsoft Visual C++ 6.0 compiler.
255<p> <h4> Compiler errors
256</h4>
257<a name="4-1-1"></a><p> <h5> "No overloaded function takes 2 parameters"
258</h5>
259<a name="4-1-1-1"></a><p> When the error occurs in code that uses the <a href="qaxfactory.html#QAXFACTORY_DEFAULT">QAXFACTORY_DEFAULT</a>
260macro, the widget class had no constructor that can be used by the
261default factory. Either add a standard widget constructor or
262implement a custom factory that doesn't require one.
263<p> When the error occurs in code that uses the <a href="qaxfactory.html#QAXFACTORY_EXPORT">QAXFACTORY_EXPORT</a>
264macro, the <a href="qaxfactory.html">QAxFactory</a> subclass had no appropriate constructor.
265Provide a public class constructor like
266<pre>
267 MyFactory( const <a href="quuid.html">QUuid</a> &amp;, const <a href="quuid.html">QUuid</a> &amp; );
268 </pre>
269
270for your factory class.
271<p> <h5> "syntax error: bad suffix on number"
272</h5>
273<a name="4-1-1-2"></a><p> The unique identifiers have not been passed as strings into the
274<a href="qaxfactory.html#QAXFACTORY_EXPORT">QAXFACTORY_EXPORT</a> or <a href="qaxfactory.html#QAXFACTORY_DEFAULT">QAXFACTORY_DEFAULT</a> macro.
275<p> <h4> Linker errors
276</h4>
277<a name="4-1-2"></a><p> <h5> "unresolved external symbol _ucm_instantiate"
278</h5>
279<a name="4-1-2-1"></a><p> The server does not export an implementation of a QAxFactory. Use
280the <a href="qaxfactory.html#QAXFACTORY_EXPORT">QAXFACTORY_EXPORT</a> macro in one of the project's
281implementation files to instantiate and export a factory, or use
282the <a href="qaxfactory.html#QAXFACTORY_DEFAULT">QAXFACTORY_DEFAULT</a> macro to use the default factory.
283<p> <h5> "_ucm_initialize already defined in ..."
284</h5>
285<a name="4-1-2-2"></a><p> The server exports more than one implementation of a <a href="qaxfactory.html">QAxFactory</a>,
286or exports the same implementation twice. If you use the default
287factory, the <a href="qaxfactory.html#QAXFACTORY_DEFAULT">QAXFACTORY_DEFAULT</a> macro must only be used once in
288the project. Use a custom QAxFactory implementation and the <a href="qaxfactory.html#QAXFACTORY_EXPORT">QAXFACTORY_EXPORT</a> macro if the server provides multiple ActiveX
289controls.
290<p> <h5> "cannot open file ... "
291</h5>
292<a name="4-1-2-3"></a><p> The ActiveX server could not shut down properly when the last
293client stopped using it. It usually takes about two seconds for
294the application to terminate, but you might have to use the task
295manager to kill the process (e.g. when a client doesn't release
296the controls properly).
297<p> <h4> Postprocessing and runtime errors
298</h4>
299<a name="4-1-3"></a><p> The <a href="activeqt.html#ActiveQt">ActiveQt</a> build system performs four commands after the linking
300of the binary to make it into an ActiveX server.
301<p> <ul>
302<li> Call the server to dump the IDL for the controls
303<li> Compile the IDL into a type library
304<li> Attach the type library as a binary resource to the server
305<li> Register the server
306</ul>
307<p> For this to work the server has to meet some requirements:
308<p> <ul>
309<li> All controls exposed can be created with nothing but a <a href="qapplication.html">QApplication</a>
310instance being present
311<li> The initial linking of the server includes a temporary type
312library resource
313<li> All dependencies required to run the server are in the system path
314(or in the path used by the calling environment; note that Visual
315Studio has it's own set of environment variables listed in the
316Tools|Options|Directories dialog).
317</ul>
318<p> If those requirements are not met one ore more of the following
319errors are likely to occure:
320<p> <h5> The server executable crashes
321</h5>
322<a name="4-1-3-1"></a><p> To generate the IDL the widgets exposed as ActiveX controls need to
323be instantiated (the constructor is called). At this point, nothing
324else but a QApplication object exists. Your widget constructor must
325not rely on any other objects to be created, e.g. it should check for
326null-pointers.
327<p> To debug your server run it with -dumpidl outputfile and check where
328it crashes.
329<p> Note that no functions of the control are called.
330<p> <h5> The server executable is not a valid Win32 application
331</h5>
332<a name="4-1-3-2"></a><p> Attaching the type library corrupted the server binary. This is a
333bug in Windows and happens only with release builds.
334<p> The first linking step has to link a dummy type library into the
335executable that can later be replaced by idc. Add a resource file
336with a type library to your project as demonstrated in the examples.
337<p> <h5> "Unable to Locate DLL"
338</h5>
339<a name="4-1-3-3"></a><p> The build system needs to run the server executable to generate
340the interface definition, and to register the server. If a dynamic
341link library the server links against is not in the path this
342might fail (e.g. Visual Studio calls the server using the
343enivronment settings specified in the "Directories" option). Make
344sure that all DLLs required by your server are located in a
345directory that is listed in the path as printed in the error
346message box.
347<p> <h5> The Server does not respond
348</h5>
349<a name="4-1-3-4"></a><p> If the system is unable to start the server (check with the task
350manager whether the server runs a process), make sure that no DLL
351the server depends on is missing from the system path (e.g. the Qt
352DLL!). Use a dependency walker to view all dependencies of the server
353binary.
354<p> If the server runs (e.g. the task manager lists a process), see
355the following section for information on debugging your server.
356<p> <h5> The Object cannot be created
357</h5>
358<a name="4-1-3-5"></a><p> If the server could be built and registered correctly during the build
359process, but the object cannot be initiliazed e.g. by the OLE/COM Object
360Viewer application, make sure that no DLL the server depends on is
361missing from the system path (e.g. the Qt DLL). Use a dependency walker
362to view all dependencies of the server binary.
363<p> If the server runs, see the following section for information on
364debugging your server.
365<p> <h3> Debugging runtime errors
366</h3>
367<a name="4-2"></a><p> To debug an in-process server in Visual Studio, set the server project
368as the active project, and specify a client "executable for debug
369session" in the project settings (e.g. use the ActiveX Test Container).
370You can set breakpoints in your code, and also step into ActiveQt and
371Qt code if you installed the debug version.
372<p> To debug an executable server, run the application in a debugger
373and start with the command line parameter "-activex". Then start
374your client and create an instance of your ActiveX control. COM
375will use the existing process for the next client trying to create
376an ActiveX control.
377<p> <h2> Implementing Controls
378</h2>
379<a name="5"></a><p> To implement an ActiveX control with Qt, create a subclass of <a href="qwidget.html">QWidget</a>
380or any existing QWidget subclass:
381<p> <pre>
382 #include &lt;<a href="qwidget-h.html">qwidget.h</a>&gt;
383
384 class MyActiveX : public <a href="qwidget.html">QWidget</a>
385 {
386 <a href="metaobjects.html#Q_OBJECT">Q_OBJECT</a>
387 </pre>
388
389<p> The <a href="metaobjects.html#Q_OBJECT">Q_OBJECT</a> macro is required to provide the <a href="metaobjects.html#meta-object">meta object</a> information
390about the widget to the ActiveQt framework.
391Use the <tt>Q_PROPERTY</tt> macro to declare properties for the ActiveX control:
392<p> <pre>
393 Q_PROPERTY( int value READ value WRITE setValue )
394 </pre>
395
396<p> Declare a standard QWidget constructor taking a parent widget and a name,
397and functions, signals and slots like any normal QWidget.
398<a href="#footnote1"><sup>(1)</sup></a><a name="footnote-call1"></a>
399<p> <pre>
400 public:
401 MyActiveX( <a href="qwidget.html">QWidget</a> *parent = 0, const char *name = 0 )
402 ...
403
404 int value() const;
405
406 public slots:
407 void setValue( int );
408 ...
409
410 signals:
411 void valueChange( int );
412 ...
413
414 };
415 </pre>
416
417<p> The ActiveQt framework will expose properties and public slots as ActiveX
418properties and methods, and signals as ActiveX events, and convert between
419the Qt data types and the equivalent COM data types.
420<p> <h3> Data Types
421</h3>
422<a name="5-1"></a><p> The Qt data types that are supported for properties are:
423<p> <center><table cellpadding="4" cellspacing="2" border="0">
424<tr bgcolor="#a2c511">
425<th valign="top">Qt data type
426<th valign="top">COM property
427<tr bgcolor="#f0f0f0">
428<td valign="top">bool
429<td valign="top">VARIANT_BOOL
430<tr bgcolor="#d0d0d0">
431<td valign="top">QString
432<td valign="top">BSTR
433<tr bgcolor="#f0f0f0">
434<td valign="top">QCString
435<td valign="top">BSTR
436<tr bgcolor="#d0d0d0">
437<td valign="top">int
438<td valign="top">int
439<tr bgcolor="#f0f0f0">
440<td valign="top">uint
441<td valign="top">unsigned int
442<tr bgcolor="#d0d0d0">
443<td valign="top">double
444<td valign="top">double
445<tr bgcolor="#f0f0f0">
446<td valign="top">Q_LLONG
447<td valign="top">CY
448<tr bgcolor="#d0d0d0">
449<td valign="top">Q_ULLONG
450<td valign="top">CY
451<tr bgcolor="#f0f0f0">
452<td valign="top">QColor
453<td valign="top">OLE_COLOR
454<tr bgcolor="#d0d0d0">
455<td valign="top">QDate
456<td valign="top">DATE
457<tr bgcolor="#f0f0f0">
458<td valign="top">QDateTime
459<td valign="top">DATE
460<tr bgcolor="#d0d0d0">
461<td valign="top">QTime
462<td valign="top">DATE
463<tr bgcolor="#f0f0f0">
464<td valign="top">QFont
465<td valign="top">IFontDisp*
466<tr bgcolor="#d0d0d0">
467<td valign="top">QPixmap
468<td valign="top">IPictureDisp*
469<a href="#footnote2"><sup>(2)</sup></a><a name="footnote-call2"></a>
470<tr bgcolor="#f0f0f0">
471<td valign="top">QVariant
472<td valign="top">VARIANT
473<tr bgcolor="#d0d0d0">
474<td valign="top">QValueList&lt;QVariant&gt;
475<td valign="top">SAFEARRAY(VARIANT)
476<tr bgcolor="#f0f0f0">
477<td valign="top">QStringList
478<td valign="top">SAFEARRAY(BSTR)
479<tr bgcolor="#d0d0d0">
480<td valign="top">QByteArray
481<td valign="top">SAFEARRAY(BYTE)
482<tr bgcolor="#f0f0f0">
483<td valign="top">QRect
484<td valign="top">User defined type
485<tr bgcolor="#d0d0d0">
486<td valign="top">QSize
487<td valign="top">User defined type
488<tr bgcolor="#f0f0f0">
489<td valign="top">QPoint
490<td valign="top">User defined type
491</table></center>
492<p> The Qt data types that are supported for parameters in signals and
493slots are:
494<center><table cellpadding="4" cellspacing="2" border="0">
495<tr bgcolor="#a2c511">
496<th valign="top">Qt data type
497<th valign="top">COM parameter
498<tr bgcolor="#d0d0d0">
499<td valign="top">bool
500<td valign="top">[in] VARIANT_BOOL
501<tr bgcolor="#f0f0f0">
502<td valign="top">bool&
503<td valign="top">[in, out] VARIANT_BOOL*
504<tr bgcolor="#d0d0d0">
505<td valign="top">QString, const <a href="qstring.html">QString</a>&
506<td valign="top">[in] BSTR
507<tr bgcolor="#f0f0f0">
508<td valign="top">QString&
509<td valign="top">[in, out] BSTR*
510<tr bgcolor="#d0d0d0">
511<td valign="top">QCString, const <a href="qcstring.html">QCString</a>&
512<td valign="top">[in] BSTR
513<tr bgcolor="#f0f0f0">
514<td valign="top">QString&
515<td valign="top">[in, out] BSTR*
516<tr bgcolor="#d0d0d0">
517<td valign="top">int
518<td valign="top">[in] int
519<tr bgcolor="#f0f0f0">
520<td valign="top">int&
521<td valign="top">[in,out] int
522<tr bgcolor="#d0d0d0">
523<td valign="top">uint
524<td valign="top">[in] unsigned int
525<tr bgcolor="#f0f0f0">
526<td valign="top">uint&
527<td valign="top">[in, out] unsigned int*
528<tr bgcolor="#d0d0d0">
529<td valign="top">double
530<td valign="top">[in] double
531<tr bgcolor="#f0f0f0">
532<td valign="top">double&
533<td valign="top">[in, out] double*
534<tr bgcolor="#d0d0d0">
535<td valign="top">QColor, const <a href="qcolor.html">QColor</a>&
536<td valign="top">[in] OLE_COLOR
537<tr bgcolor="#f0f0f0">
538<td valign="top">QColor&
539<td valign="top">[in, out] OLE_COLOR*
540<tr bgcolor="#d0d0d0">
541<td valign="top">QDate, const <a href="qdate.html">QDate</a>&
542<td valign="top">[in] DATE
543<tr bgcolor="#f0f0f0">
544<td valign="top">QDate&
545<td valign="top">[in, out] DATE*
546<tr bgcolor="#d0d0d0">
547<td valign="top">QDateTime, const <a href="qdatetime.html">QDateTime</a>&
548<td valign="top">[in] DATE
549<tr bgcolor="#f0f0f0">
550<td valign="top">QDateTime&
551<td valign="top">[in, out] DATE*
552<tr bgcolor="#d0d0d0">
553<td valign="top">QFont, const <a href="qfont.html">QFont</a>&
554<td valign="top">[in] IFontDisp*
555<tr bgcolor="#f0f0f0">
556<td valign="top">QFont&
557<td valign="top">[in, out] IFontDisp**
558<tr bgcolor="#d0d0d0">
559<td valign="top">QPixmap, const <a href="qpixmap.html">QPixmap</a>&
560<td valign="top">[in] IPictureDisp*
561<tr bgcolor="#f0f0f0">
562<td valign="top">QPixmap&
563<td valign="top">[in, out] IPictureDisp**
564<tr bgcolor="#d0d0d0">
565<td valign="top">QValueList&lt;QVariant&gt;, const <a href="qvaluelist.html">QValueList</a>&lt;QVariant&gt;&
566<td valign="top">[in] SAFEARRAY(VARIANT)
567<tr bgcolor="#f0f0f0">
568<td valign="top">QValueList&lt;QVariant&gt;&
569<td valign="top">[in, out] SAFEARRAY(VARIANT)*
570<tr bgcolor="#d0d0d0">
571<td valign="top">QStringList, const <a href="qstringlist.html">QStringList</a>&
572<td valign="top">[in] SAFEARRAY(BSTR)
573<tr bgcolor="#f0f0f0">
574<td valign="top">QStringList&
575<td valign="top">[in, out] SAFEARRAY(BSTR)*
576<tr bgcolor="#d0d0d0">
577<td valign="top">QByteArray, const <a href="qbytearray.html">QByteArray</a>&
578<td valign="top">[in] SAFEARRAY(BYTE)
579<tr bgcolor="#f0f0f0">
580<td valign="top">QByteArray&
581<td valign="top">[in, out] SAFEARRAY(BYTE)*
582<tr bgcolor="#d0d0d0">
583<td valign="top">QObject*
584<td valign="top">[in] IDispatch*
585<tr bgcolor="#f0f0f0">
586<td valign="top">QRect&
587<a href="#footnote3"><sup>(3)</sup></a><a name="footnote-call3"></a>
588<td valign="top">[in, out] struct <a href="qrect.html">QRect</a> (user defined)
589<tr bgcolor="#d0d0d0">
590<td valign="top">QSize&
591<td valign="top">[in, out] struct <a href="qsize.html">QSize</a> (user defined)
592<tr bgcolor="#f0f0f0">
593<td valign="top">QPoint&
594<td valign="top">[in, out] struct <a href="qpoint.html">QPoint</a> (user defined)
595</table></center>
596<p> Also supported are exported enums and sets (see Q_ENUMS and Q_SETS).
597The in-parameter types are also supported as return values.
598<p> Properties and signals/slots that have parameters using any other
599data types are ignored by the QActiveX framework.
600<p> <h3> Sub-Objects
601</h3>
602<a name="5-2"></a><p> COM objects can have multiple sub-objects that can represent a sub element
603of the COM object. A COM object representing a multi-document spread sheet
604application can for example provide one sub-object for each spread sheet.
605<p> Any <a href="qobject.html">QObject</a> subclass can be used as the type for a sub object in ActiveX. The
606<a href="qaxfactory.html">QAxFactory</a> implementation (see below) needs to return the classname of the
607sub type as one key in the featureList() implementation, as well as the IDs
608for the COM class, the interface and event interface of that type. Then the
609type can be used as e.g. the return value or paramter of a slot.
610<p> <h3> Property Notification
611</h3>
612<a name="5-3"></a><p> To make the properties bindable for the ActiveX client, use multiple
613inheritance from the <a href="qaxbindable.html">QAxBindable</a> class:
614<p>
615 <pre>
616 #include &lt;qwidget.h&gt;
617 <b>#include &lt;qaxbindable.h&gt;</b>
618
619 class MyActiveX : public <a href="qwidget.html">QWidget</a><b>, public QAxBindable</b>
620 {
621 Q_OBJECT
622 </pre>
623
624When implementing the property write functions, use the
625QAxBindable class's requestPropertyChange() and propertyChanged()
626functions to allow ActiveX clients to bind to the control
627properties.
628<a href="#footnote4"><sup>(4)</sup></a><a name="footnote-call4"></a>
629<p> <h2> Serving Controls
630</h2>
631<a name="6"></a><p> To make an ActiveX control available to the COM system it must
632be registered in the system registry using five unique
633identifiers. These identifiers are provided by tools like <tt>guidgen</tt> or <tt>uuidgen</tt>. The registration information allows COM to
634localize the binary providing a requested ActiveX control,
635marshall remote procedure calls to the control and read type
636information about the methods and properties exposed by the
637control.
638<p> To create the ActiveX control when the client asks for it the
639server must export an implementation of a <a href="qaxfactory.html">QAxFactory</a>. Use the
640default factory when the server provides only a single ActiveX
641control, and implement a subclass of QAxFactory to provide
642multiple ActiveX controls. The default factory is available
643through a macro that takes the identifiers COM requires to locate
644the ActiveX control on the target system:
645<p> <pre>
646 QAXFACTORY_DEFAULT ( MyActiveX,
647 "{ad90301a-849e-4e8b-9a91-0a6dc5f6461f}",
648 "{87a5b65e-7fa9-4dc6-a176-47295988dcbd}",
649 "{a6130ae9-8327-47ec-815b-d0b45a0d6e5e}",
650 "{26c4e136-4e23-4347-af37-faf933b027e9}",
651 "{a8f21901-7ff7-4f6a-b939-789620c03d83}" )
652 </pre>
653
654<p> The <a href="qaxfactory.html">QAxFactory class documentation</a> explains
655how to use this macro, and how to implement and use custom factories.
656<p> For out-of-process executable servers you can implement a main()
657function to instantiate a <a href="qapplication.html">QApplication</a> object and enter the event
658loop just like any normal Qt application. By default the
659application will start as a standard Qt application, but if you
660pass <tt>-activex</tt> on the command line it will start as an ActiveX
661server. Use <a href="qaxfactory.html#isServer">QAxFactory::isServer</a>() to create and run a standard
662application interface, or to prevent a stand-alone execution:
663<p>
664 <pre>
665 #include &lt;qapplication.h&gt;
666 <b>#include &lt;qaxfactory.h&gt;</b>
667
668 int main( int argc, char **argv )
669 {
670 QApplication app( argc, argv );
671 <b>if ( !QAxFactory::isServer() ) {
672 // create and show main window...
673 }</b>
674 return app.exec();
675 }
676 </pre>
677
678This is however not necessary as ActiveQt provides a default implementation
679of a main function. The default implemenation calls <a href="qaxfactory.html#startServer">QAxFactory::startServer</a>(),
680creates a QApplication instance and calls exec().
681<p> To build the ActiveX server executable run <a href="qmake-manual.html">qmake</a> to generate the makefile, and use your compiler's
682make tool as for any other Qt application. The make process will
683also register the controls in the system registry by calling the
684resulting executable with the <tt>-regserver</tt> command line option.
685<p> If the ActiveX server is an executable, the following command line
686options are supported:
687<center><table cellpadding="4" cellspacing="2" border="0">
688<tr bgcolor="#a2c511"> <th valign="top">Option <th valign="top">Result
689<tr bgcolor="#d0d0d0"> <td valign="top"><tt>-regserver</tt> <td valign="top">Registers the server in the system registry
690<tr bgcolor="#f0f0f0"> <td valign="top"><tt>-unregserver</tt> <td valign="top">Unregisters the server from the system registry
691<tr bgcolor="#d0d0d0"> <td valign="top"><tt>-activex</tt> <td valign="top">Starts the application as an ActiveX server
692<tr bgcolor="#f0f0f0"> <td valign="top"><tt>-dumpidl &lt;file&gt; -version x.y</tt> <td valign="top">Writes the server's IDL to the
693specified file. The type library will have version x.y
694</table></center>
695<p> In-process servers can be registered using the <tt>regsvr32</tt> tool available
696on all Windows systems.
697<p> <h3> Distributing QAxServer binaries
698</h3>
699<a name="6-1"></a><p> ActiveX servers written with Qt can use Qt either as a shared
700library, or have Qt linked statically into the binary. Both ways
701will produce rather large packages (either the server binary
702itself becomes large, or you have to ship the Qt DLL).
703<p> <h4> Installing stand-alone Servers
704</h4>
705<a name="6-1-1"></a><p> When your ActiveX server can also run as a stand-alone application,
706run the server executable with the <tt>-regserver</tt> command line
707parameter after installing the executable on the target system.
708After that the controls provided by the server will be available to
709ActiveX clients.
710<p> <h4> Installing In-process Servers
711</h4>
712<a name="6-1-2"></a><p> When your ActiveX server is part of an installation package, use the
713<tt>regsvr32</tt> tool provided by Microsoft to register the controls on
714the target system. If this tool is not present, load the DLL into
715your installer process, resolve the <tt>DllRegisterServer</tt> symbol and
716call the function:
717<p> <pre>
718 HMODULE dll = LoadLibrary( "myserver.dll" );
719 typedef HRESULT(__stdcall *DllRegisterServerProc)();
720 DllRegisterServerProc DllRegisterServer =
721 (DllRegisterServerProc)GetProcAddress( dll, "DllRegisterServer" );
722
723 HRESULT res = E_FAIL;
724 if ( DllRegisterServer )
725 res = DllRegisterServer();
726 if ( res != S_OK )
727 // error handling
728 </pre>
729
730<p> <h4> Distributing Servers over the Internet
731</h4>
732<a name="6-1-3"></a><p> If you want to use controls in your server in web-pages you need to
733make the server available to the browser used to view your page, and
734you need to specify the location of the server package in your page.
735<p> To specify the location of a server, use the CODEBASE attribute in
736the OBJECT tag of your web-site. The value can point to the server
737file itself, to an <tt>INF</tt> file listing other files the server requires
738(e.g. the Qt DLL), or a compressed <tt>CAB</tt> archive.
739<p> INF and CAB files are documented in almost every book available about
740ActiveX and COM programming as well as in the MSDN library and various
741other Online resources. The examples include INF files that can be used
742to build CAB archives:
743<p>
744
745<pre> [version]
746 signature="$CHICAGO$"
747 AdvancedINF=2.0
748 [Add.Code]
749 simpleax.exe=simpleax.exe
750 [simpleax.exe]
751 file-win32-x86=thiscab
752 clsid={DF16845C-92CD-4AAB-A982-EB9840E74669}
753 RegisterServer=yes
754</pre>
755<p> The CABARC tool from Microsoft can easily generate CAB archives:
756<pre> cabarc N simpleax.cab simpleax.exe simple.inf </pre>
757
758<p> The INF files assume a static build of Qt, so no dependencies to other DLLs
759are listed in the INF files. To distribute an ActiveX server depending on
760DLLs you must add the dependencies, and provide the library files
761with the archive.
762<p> <h2> Using the Controls
763</h2>
764<a name="7"></a><p> To use the ActiveX controls, e.g. to embed them in a web page, use
765the <tt>&lt;object&gt;</tt> HTML tag.
766<p> <pre>
767 &lt;object ID="MyActiveX1" CLASSID="CLSID:ad90301a-849e-4e8b-9a91-0a6dc5f6461f"&gt;
768 ...
769 &lt;\object&gt;
770 </pre>
771
772<p> To initialize the control's properties, use
773<pre>
774 &lt;object ID=...&gt;
775 &lt;param name="name" value="value"&gt;
776 &lt;\object&gt;
777 </pre>
778
779<p> If the web browser supports scripting use JavaScript, VBScript and
780forms to script the control. The <a href="qaxserver-examples.html">examples</a> include demonstration HTML pages for the
781example controls.
782<p> <h3> Supported and Unsupported ActiveX clients
783</h3>
784<a name="7-1"></a><p> The following is largly based on our own experiements with ActiveX
785controls and client applications, and is by no means complete.
786<p> <h4> Supported Clients
787</h4>
788<a name="7-1-1"></a><p> These standard applications work with ActiveX controls developed with
789ActiveQt. Note that some clients support only in-process controls.
790<p> <ul>
791<li> Internet Explorer
792<li> Microsoft ActiveX Control Test Container
793<li> Microsoft Visual Studio 6.0
794<li> Microsoft Visual Studio.NET/2003
795<li> Microsoft Visual Basic 6.0
796<li> MFC- and ATL-based containers
797<li> Sybase PowerBuilder
798<li> ActiveQt based containers
799</ul>
800<p> Microsoft Office applications are supported, but you need to register
801the controls as "Insertable" objects. Reimplement <tt>QAxFactory::registerClass</tt>
802to add this attribute to the COM class, or set the "Insertable" class info
803for your class to "yes" using the Q_CLASSINFO macro.
804<p> <h4> Unsupported Clients
805</h4>
806<a name="7-1-2"></a><p> We have not managed to make ActiveQt based COM objects work with the
807following client applications.
808<p> <ul>
809<li> Borland C++ Builder (Versions 5 and 6)
810<li> Borland Delphi
811</ul>
812<p> <h2> Enhanced features
813</h2>
814<a name="8"></a><p> <h3> Fewer methods and properties
815</h3>
816<a name="8-1"></a><p> By default all ActiveX controls expose not only their own methods
817and properties to ActiveX clients, but also those of all super
818classes, including <a href="qwidget.html">QWidget</a>.
819<p> This can be controlled by reimplementing <a href="qaxfactory.html">QAxFactory</a>'s
820exposeToSuperClass() function. Reimplement the function to return
821the last (furthest up the inheritance hierarchy) super class that
822should be exposed:
823<p> <pre>
824 QString MyFactory::exposeToSuperClass( const <a href="qstring.html">QString</a> &amp;key ) const
825 {
826 if ( key == "SmallActiveX" )
827 return key;
828 return QAxFactory::exposeToSuperClass( key );
829 }
830 </pre>
831
832<p> The SmallActiveX control will only expose its own functions and
833properties to clients, while all other ActiveX controls provided
834by this factory will expose their own functions and properties and
835also those of all their super classes including QWidget. The
836SmallActiveX class can of course propagate some of the QWidget
837functions and properties into its own interface.
838<p> <h3> Class Information and Tuning
839</h3>
840<a name="8-2"></a><p> An alternative way to reimplementing QAxFactory to have more control
841about how objects are registered or exposed is to provide class
842specific information using the Q_CLASSINFO macro, which is part of
843Qt's meta object system.
844<p> <center><table cellpadding="4" cellspacing="2" border="0">
845<tr bgcolor="#a2c511">
846<th valign="top">Key
847<th valign="top">Meaning of value
848<tr bgcolor="#d0d0d0">
849<td valign="top">Version
850<td valign="top">The version of the class (1.0 is default)
851<tr bgcolor="#f0f0f0">
852<td valign="top">Description
853<td valign="top">A string describing the class.
854<tr bgcolor="#d0d0d0">
855<td valign="top">ClassID
856<td valign="top">The class ID.
857You must reimplement QAxFactory::classID if not specified.
858<tr bgcolor="#f0f0f0">
859<td valign="top">InterfaceID
860<td valign="top">The interface ID.
861You must reimplement QAxFactory::interfaceID if not specified.
862<tr bgcolor="#d0d0d0">
863<td valign="top">EventsID
864<td valign="top">The event interface ID.
865No signals are exposed as COM events if not specified.
866<tr bgcolor="#f0f0f0">
867<td valign="top">DefaultProperty
868<td valign="top">The property specified represents the default property of this class.
869Ie. the default property of a push button would be "text".
870<tr bgcolor="#d0d0d0">
871<td valign="top">DefaultSignal
872<td valign="top">The signal specified respresents the default signal of this class.
873Ie. the default signal of a push button would be "clicked".
874<tr bgcolor="#f0f0f0">
875<td valign="top">LicenseKey
876<td valign="top">Object creation requires the specified license key. The key can be
877empty to require a licensed machine. By default classes are not
878licensed. Also see the following section.
879<tr bgcolor="#d0d0d0">
880<td valign="top">StockEvents
881<td valign="top">Objects expose stock events if value is "yes".
882See <a href="qaxfactory.html#hasStockEvents">QAxFactory::hasStockEvents</a>()
883<tr bgcolor="#f0f0f0">
884<td valign="top">ToSuperClass
885<td valign="top">Objects expose functionality of all super classes up to and
886including the class name in value.
887See <a href="qaxfactory.html#exposeToSuperClass">QAxFactory::exposeToSuperClass</a>()
888<tr bgcolor="#d0d0d0">
889<td valign="top">Insertable
890<td valign="top">If the value is "yes" the class is registered to be "Insertable"
891and will be listed in OLE 2 containers (ie. Microsoft Office). This
892attribute is not be set by default.
893<tr bgcolor="#f0f0f0">
894<td valign="top">Aggregatable
895<td valign="top">If the value is "no" the class does not support aggregation. By
896default aggregation is supported.
897<tr bgcolor="#d0d0d0">
898<td valign="top">Creatable
899<td valign="top">If the value is "no" the class cannot be created by the client,
900and is only available through the API of another class (ie. the
901class is a sub-type).
902<tr bgcolor="#f0f0f0">
903<td valign="top">RegisterObject
904<td valign="top">If the value is "yes" objects of this class are registered with
905OLE and accessible from the running object table (ie. clients
906can connect to an already running instance of this class). This
907attribute is only supported in out-of-process servers.
908</table></center>
909<p> Note that both keys and values are case sensitive.
910<p> The following declares version 2.0 of a class that exposes only its
911own API, and is available in the "Insert Objects" dialog of Microsoft
912Office applications.
913<p>
914 <pre>
915 class MyActiveX : public <a href="qwidget.html">QWidget</a>
916 {
917 Q_OBJECT
918 <b>Q_CLASSINFO("Version", "2.0")
919 Q_CLASSINFO("ClassID", "{7a4cffd8-cbcd-4ae9-ae7e-343e1e5710df}")
920 Q_CLASSINFO("InterfaceID", "{6fb035bf-8019-48d8-be51-ef05427d8994}")
921 Q_CLASSINFO("EventsID", "{c42fffdf-6557-47c9-817a-2da2228bc29c}")
922 Q_CLASSINFO("Insertable", "yes")
923 Q_CLASSINFO("ToSuperClass", "MyActiveX")</b>
924
925 Q_PROPERTY( ...
926 public:
927 MyActiveX(QWidget *parent = 0, const char *name = 0);
928
929 ...
930 };
931 </pre>
932
933<h3> Developing licensed components
934</h3>
935<a name="8-3"></a><p> If you develop components you might want to control who is able to instantiate
936those components. Since the server binary can be shipped to and registered on
937any client machine it is possible for anybody to use those components in his
938own software.
939<p> Licensing components can be done using a variety of techniques, e.g. the code
940creating the control can provide a license key, or the machine on which the
941control is supposed to run needs to be licensed.
942<p> To mark a Qt class as licensed specify a "LicenseKey" using the <tt>Q_CLASSINFO</tt>
943macro.
944
945 <pre>
946 class MyLicensedControl : public <a href="qwidget.html">QWidget</a>
947 {
948 Q_OBJECT
949 <b>Q_CLASSINFO("LicenseKey", "&lt;key string&gt;")</b>
950 ...
951 };
952 </pre>
953
954The key is required to be able to create an instance of <tt>MyLicensedControl</tt>
955on a machine that is not licensed itself. The licensed developer can now
956redistributes the server binary with his application, which creates the control
957using the value of "LicenseKey", while users of the application cannot create
958the control without the license key.
959<p> If a single license key for the control is not sufficient (ie. you want
960differnet developers to receive different license keys) you can specify an
961empty key to indicate that the control requires a license, and reimplement
962<a href="qaxfactory.html#validateLicenseKey">QAxFactory::validateLicenseKey</a>() to verify that a license exists on the
963system (ie. through a license file).
964<p> <h3> More Interfaces
965</h3>
966<a name="8-4"></a><p> ActiveX controls provided by ActiveQt servers support a minimal set of COM
967interfaces to implement the OLE specifications. When the ActiveX class inherits
968from the <a href="qaxbindable.html">QAxBindable</a> class it can also implement additional COM interfaces.
969<p> Create a new subclass of <a href="qaxaggregated.html">QAxAggregated</a> and use multiple inheritance
970to subclass additional COM interface classes.
971<p> <pre>
972 class AxImpl : public <a href="qaxaggregated.html">QAxAggregated</a>, public ISomeCOMInterface
973 {
974 public:
975 AxImpl() {}
976
977 long queryInterface( const <a href="quuid.html">QUuid</a> &amp;iid, void **iface );
978
979 // IUnknown
980 QAXAGG_IUNKNOWN
981
982 // ISomeCOMInterface
983 ...
984 }
985 </pre>
986
987<p> Reimplement the <tt>queryInterface()</tt> function to support the additional
988COM interfaces.
989<p> <pre>
990 long AxImpl::queryInterface( const <a href="quuid.html">QUuid</a> &amp;iid, void **iface )
991 {
992 *iface = 0;
993 if ( iid == IID_ISomeCOMInterface )
994 *iface = (ISomeCOMInterface*)this;
995 else
996 return E_NOINTERFACE;
997
998 AddRef();
999 return S_OK;
1000 }
1001 </pre>
1002
1003<p> Since <tt>ISomeCOMInterface</tt> is a subclass of <tt>IUnknown</tt> you will have
1004to implement the <tt>QueryInterface</tt>, <tt>AddRef</tt> and <tt>Release</tt> functions.
1005Use the <tt>QAXAGG_IUNKNOWN</tt> macro in your class definition to do that. If
1006you implement the IUnknown functions manually, delegate the calls to the
1007interface pointer returned by the controllingUnknown() function, e.g.
1008<pre>
1009 HRESULT AxImpl::QueryInterface( REFIID iid, void **iface )
1010 {
1011 return controllingUnknown()-&gt;QueryInterface( iid, iface );
1012 }
1013 </pre>
1014
1015Do not support the <tt>IUnknown</tt> interface itself in your <tt>queryInterface()</tt>
1016implementation.
1017<p> Implement the methods of the COM interfaces, and use QAxAggregated::Object()
1018if you need to make calls to the <a href="qobject.html">QObject</a> subclass implementing the control.
1019<p> In your <a href="qaxbindable.html">QAxBindable</a> subclass, implement <tt>createAggregate()</tt> to return
1020a new object of the <a href="qaxaggregated.html">QAxAggregated</a> subclass.
1021<p>
1022 <pre>
1023 class MyActiveX : public <a href="qwidget.html">QWidget</a>,
1024 <b>public QAxBindable</b>
1025 {
1026 Q_OBJECT
1027 public:
1028 MyActiveX( QWidget *parent, const char *name = 0 );
1029
1030 <b>QAxAggregated *createAggregate()
1031 {
1032 return new AxImpl();
1033 }
1034 </b>
1035 };
1036 </pre>
1037
1038<hr>
1039<ol> <li><a name="footnote1"></a>
1040
1041If a standard constructor is not present the compiler will issue
1042an error "no overloaded function takes 2 parameters" when using
1043the default factory through the <a href="qaxfactory.html#QAXFACTORY_DEFAULT">QAXFACTORY_DEFAULT</a> macro. If you
1044cannot provide a standard constructor you must implement a <a href="qaxfactory.html">QAxFactory</a> custom factory and call the constructor you have in
1045your implementation of QAxFactory::create.
1046 <a href="#footnote-call1">Back...</a> <li><a name="footnote2"></a>
1047
1048COM cannot marshal IPictureDisp accross process boundaries,
1049so <a href="qpixmap.html">QPixmap</a> properties cannot be called for out-of-process servers. You
1050can however marshal the image data via e.g. temporary files. See the
1051Microsoft
1052<a href="http://support.microsoft.com/default.aspx?scid=kb;[LN];Q150034">KB article
1053 Q150034</a> for more information.
1054 <a href="#footnote-call2">Back...</a> <li><a name="footnote3"></a>
1055
1056OLE needs to marshal user defined types by reference (ByRef), and cannot
1057marshal them by value (ByVal). This is why const-references and object
1058parameters are not supported for <a href="qrect.html">QRect</a>, <a href="qsize.html">QSize</a> and <a href="qpoint.html">QPoint</a>. Also note that
1059servers with this datatype require Windows 98 or DCOM 1.2 to be installed.
1060 <a href="#footnote-call3">Back...</a> <li><a name="footnote4"></a>
1061
1062This is not required, but gives the client more control over
1063the ActiveX control.
1064 <a href="#footnote-call4">Back...</a></ol>
1065</hr>
1066<!-- eof -->
1067<p><address><hr><div align=center>
1068<table width=100% cellspacing=0 border=0><tr>
1069<td>Copyright &copy; 2007
1070<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
1071<td align=right><div align=right>Qt 3.3.8</div>
1072</table></div></address></body>
1073</html>
Note: See TracBrowser for help on using the repository browser.