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"><!--
|
---|
8 | fn { margin-left: 1cm; text-indent: -1cm; }
|
---|
9 | a:link { color: #004faf; text-decoration: none }
|
---|
10 | a:visited { color: #672967; text-decoration: none }
|
---|
11 | body { 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 Classes</font></a>
|
---|
23 | | <a href="mainclasses.html">
|
---|
24 | <font color="#004faf">Main 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 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
|
---|
144 | functions required to turn a standard Qt binary into an ActiveX
|
---|
145 | control server.
|
---|
146 | <p> This module is part of the <a href="activeqt.html">ActiveQt
|
---|
147 | framework</a>. (To incorporate ActiveX controls in a Qt
|
---|
148 | application 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
|
---|
154 | ActiveX 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>
|
---|
158 | of 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>)
|
---|
162 | enter the <tt>control</tt> subdirectory and run <tt>qmake</tt> to generate the
|
---|
163 | makefile, and use the make tool (<tt>nmake</tt> for VC++, <tt>make</tt> for Borland)
|
---|
164 | to 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
|
---|
169 | QAxServer library you must add <tt>activeqt</tt> as a CONFIG setting
|
---|
170 | in your <tt>.pro</tt> file.
|
---|
171 | <p> An out-of-process executable server is generated from a <tt>.pro</tt>
|
---|
172 | file 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
|
---|
192 | framework and can be used from their usual location (specify a
|
---|
193 | path in the <tt>.pro</tt> file), or copied into the project directory.
|
---|
194 | You can modify these files as long as it includes any file as the
|
---|
195 | type library entry, ie. you can add version information or use a
|
---|
196 | different toolbox icon.
|
---|
197 | <p> The <tt>activeqt</tt> configuration will cause the <tt>qmake</tt> tool to add the
|
---|
198 | required 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
|
---|
202 | the binary
|
---|
203 | <li> register the server
|
---|
204 | </ul>
|
---|
205 | <p> Additionally you can specify a version number using the <tt>VERSION</tt>
|
---|
206 | variable, e.g.
|
---|
207 | <pre>
|
---|
208 | TEMPLATE = lib
|
---|
209 | VERSION = 2.5
|
---|
210 | ...
|
---|
211 | </pre>
|
---|
212 |
|
---|
213 | The version number specified will be used as the version of the type
|
---|
214 | library 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
|
---|
218 | or as a shared library in the client process depends mainly on the
|
---|
219 | type of controls you want to provide in the server.
|
---|
220 | <p> An executable server has the advantage of being able to run as a
|
---|
221 | stand-alone application, but adds considerable overhead to the
|
---|
222 | communication between the ActiveX client and the control. If the
|
---|
223 | control has a programming error only the server process running
|
---|
224 | the control will crash, and the client application will probably
|
---|
225 | continue to run.
|
---|
226 | <p> An in-process server is usually smaller and has faster startup
|
---|
227 | time. The communication between client and server is done directly
|
---|
228 | through virtual function calls and does not introduce the overhead
|
---|
229 | required for remote procedure calls. But if the server crashes the
|
---|
230 | client application is likely to crash as well.
|
---|
231 | <p> Both server types can use Qt either as a shared library, or
|
---|
232 | statically 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
|
---|
236 | must be extended to include some additional build steps that are
|
---|
237 | used when the <tt>.pro</tt> file includes <tt>activeqt</tt> in the <tt>CONFIG</tt>
|
---|
238 | settings. 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
|
---|
242 | generate an IDL description of the ActiveX controls provided by
|
---|
243 | the 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
|
---|
246 | executable
|
---|
247 | </ul>
|
---|
248 | <p> Attaching resources to an executable is not supported by
|
---|
249 | Windows 95/98/ME, but a server built on
|
---|
250 | Windows 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
|
---|
254 | Microsoft 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>
|
---|
260 | macro, the widget class had no constructor that can be used by the
|
---|
261 | default factory. Either add a standard widget constructor or
|
---|
262 | implement 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>
|
---|
264 | macro, the <a href="qaxfactory.html">QAxFactory</a> subclass had no appropriate constructor.
|
---|
265 | Provide a public class constructor like
|
---|
266 | <pre>
|
---|
267 | MyFactory( const <a href="quuid.html">QUuid</a> &, const <a href="quuid.html">QUuid</a> & );
|
---|
268 | </pre>
|
---|
269 |
|
---|
270 | for 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
|
---|
280 | the <a href="qaxfactory.html#QAXFACTORY_EXPORT">QAXFACTORY_EXPORT</a> macro in one of the project's
|
---|
281 | implementation files to instantiate and export a factory, or use
|
---|
282 | the <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>,
|
---|
286 | or exports the same implementation twice. If you use the default
|
---|
287 | factory, the <a href="qaxfactory.html#QAXFACTORY_DEFAULT">QAXFACTORY_DEFAULT</a> macro must only be used once in
|
---|
288 | the project. Use a custom QAxFactory implementation and the <a href="qaxfactory.html#QAXFACTORY_EXPORT">QAXFACTORY_EXPORT</a> macro if the server provides multiple ActiveX
|
---|
289 | controls.
|
---|
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
|
---|
293 | client stopped using it. It usually takes about two seconds for
|
---|
294 | the application to terminate, but you might have to use the task
|
---|
295 | manager to kill the process (e.g. when a client doesn't release
|
---|
296 | the 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
|
---|
300 | of 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>
|
---|
310 | instance being present
|
---|
311 | <li> The initial linking of the server includes a temporary type
|
---|
312 | library 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
|
---|
315 | Studio has it's own set of environment variables listed in the
|
---|
316 | Tools|Options|Directories dialog).
|
---|
317 | </ul>
|
---|
318 | <p> If those requirements are not met one ore more of the following
|
---|
319 | errors 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
|
---|
323 | be instantiated (the constructor is called). At this point, nothing
|
---|
324 | else but a QApplication object exists. Your widget constructor must
|
---|
325 | not rely on any other objects to be created, e.g. it should check for
|
---|
326 | null-pointers.
|
---|
327 | <p> To debug your server run it with -dumpidl outputfile and check where
|
---|
328 | it 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
|
---|
333 | bug in Windows and happens only with release builds.
|
---|
334 | <p> The first linking step has to link a dummy type library into the
|
---|
335 | executable that can later be replaced by idc. Add a resource file
|
---|
336 | with 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
|
---|
340 | the interface definition, and to register the server. If a dynamic
|
---|
341 | link library the server links against is not in the path this
|
---|
342 | might fail (e.g. Visual Studio calls the server using the
|
---|
343 | enivronment settings specified in the "Directories" option). Make
|
---|
344 | sure that all DLLs required by your server are located in a
|
---|
345 | directory that is listed in the path as printed in the error
|
---|
346 | message 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
|
---|
350 | manager whether the server runs a process), make sure that no DLL
|
---|
351 | the server depends on is missing from the system path (e.g. the Qt
|
---|
352 | DLL!). Use a dependency walker to view all dependencies of the server
|
---|
353 | binary.
|
---|
354 | <p> If the server runs (e.g. the task manager lists a process), see
|
---|
355 | the 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
|
---|
359 | process, but the object cannot be initiliazed e.g. by the OLE/COM Object
|
---|
360 | Viewer application, make sure that no DLL the server depends on is
|
---|
361 | missing from the system path (e.g. the Qt DLL). Use a dependency walker
|
---|
362 | to view all dependencies of the server binary.
|
---|
363 | <p> If the server runs, see the following section for information on
|
---|
364 | debugging 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
|
---|
368 | as the active project, and specify a client "executable for debug
|
---|
369 | session" in the project settings (e.g. use the ActiveX Test Container).
|
---|
370 | You can set breakpoints in your code, and also step into ActiveQt and
|
---|
371 | Qt code if you installed the debug version.
|
---|
372 | <p> To debug an executable server, run the application in a debugger
|
---|
373 | and start with the command line parameter "-activex". Then start
|
---|
374 | your client and create an instance of your ActiveX control. COM
|
---|
375 | will use the existing process for the next client trying to create
|
---|
376 | an 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>
|
---|
380 | or any existing QWidget subclass:
|
---|
381 | <p> <pre>
|
---|
382 | #include <<a href="qwidget-h.html">qwidget.h</a>>
|
---|
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
|
---|
390 | about the widget to the ActiveQt framework.
|
---|
391 | Use 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,
|
---|
397 | and 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
|
---|
418 | properties and methods, and signals as ActiveX events, and convert between
|
---|
419 | the 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<QVariant>
|
---|
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
|
---|
493 | slots 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<QVariant>, const <a href="qvaluelist.html">QValueList</a><QVariant>&
|
---|
566 | <td valign="top">[in] SAFEARRAY(VARIANT)
|
---|
567 | <tr bgcolor="#f0f0f0">
|
---|
568 | <td valign="top">QValueList<QVariant>&
|
---|
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).
|
---|
597 | The in-parameter types are also supported as return values.
|
---|
598 | <p> Properties and signals/slots that have parameters using any other
|
---|
599 | data 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
|
---|
603 | of the COM object. A COM object representing a multi-document spread sheet
|
---|
604 | application 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
|
---|
607 | sub type as one key in the featureList() implementation, as well as the IDs
|
---|
608 | for the COM class, the interface and event interface of that type. Then the
|
---|
609 | type 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
|
---|
613 | inheritance from the <a href="qaxbindable.html">QAxBindable</a> class:
|
---|
614 | <p>
|
---|
615 | <pre>
|
---|
616 | #include <qwidget.h>
|
---|
617 | <b>#include <qaxbindable.h></b>
|
---|
618 |
|
---|
619 | class MyActiveX : public <a href="qwidget.html">QWidget</a><b>, public QAxBindable</b>
|
---|
620 | {
|
---|
621 | Q_OBJECT
|
---|
622 | </pre>
|
---|
623 |
|
---|
624 | When implementing the property write functions, use the
|
---|
625 | QAxBindable class's requestPropertyChange() and propertyChanged()
|
---|
626 | functions to allow ActiveX clients to bind to the control
|
---|
627 | properties.
|
---|
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
|
---|
632 | be registered in the system registry using five unique
|
---|
633 | identifiers. These identifiers are provided by tools like <tt>guidgen</tt> or <tt>uuidgen</tt>. The registration information allows COM to
|
---|
634 | localize the binary providing a requested ActiveX control,
|
---|
635 | marshall remote procedure calls to the control and read type
|
---|
636 | information about the methods and properties exposed by the
|
---|
637 | control.
|
---|
638 | <p> To create the ActiveX control when the client asks for it the
|
---|
639 | server must export an implementation of a <a href="qaxfactory.html">QAxFactory</a>. Use the
|
---|
640 | default factory when the server provides only a single ActiveX
|
---|
641 | control, and implement a subclass of QAxFactory to provide
|
---|
642 | multiple ActiveX controls. The default factory is available
|
---|
643 | through a macro that takes the identifiers COM requires to locate
|
---|
644 | the 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
|
---|
655 | how 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()
|
---|
657 | function to instantiate a <a href="qapplication.html">QApplication</a> object and enter the event
|
---|
658 | loop just like any normal Qt application. By default the
|
---|
659 | application will start as a standard Qt application, but if you
|
---|
660 | pass <tt>-activex</tt> on the command line it will start as an ActiveX
|
---|
661 | server. Use <a href="qaxfactory.html#isServer">QAxFactory::isServer</a>() to create and run a standard
|
---|
662 | application interface, or to prevent a stand-alone execution:
|
---|
663 | <p>
|
---|
664 | <pre>
|
---|
665 | #include <qapplication.h>
|
---|
666 | <b>#include <qaxfactory.h></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 |
|
---|
678 | This is however not necessary as ActiveQt provides a default implementation
|
---|
679 | of a main function. The default implemenation calls <a href="qaxfactory.html#startServer">QAxFactory::startServer</a>(),
|
---|
680 | creates 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
|
---|
682 | make tool as for any other Qt application. The make process will
|
---|
683 | also register the controls in the system registry by calling the
|
---|
684 | resulting executable with the <tt>-regserver</tt> command line option.
|
---|
685 | <p> If the ActiveX server is an executable, the following command line
|
---|
686 | options 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 <file> -version x.y</tt> <td valign="top">Writes the server's IDL to the
|
---|
693 | specified 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
|
---|
696 | on 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
|
---|
700 | library, or have Qt linked statically into the binary. Both ways
|
---|
701 | will produce rather large packages (either the server binary
|
---|
702 | itself 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,
|
---|
706 | run the server executable with the <tt>-regserver</tt> command line
|
---|
707 | parameter after installing the executable on the target system.
|
---|
708 | After that the controls provided by the server will be available to
|
---|
709 | ActiveX 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
|
---|
714 | the target system. If this tool is not present, load the DLL into
|
---|
715 | your installer process, resolve the <tt>DllRegisterServer</tt> symbol and
|
---|
716 | call 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
|
---|
733 | make the server available to the browser used to view your page, and
|
---|
734 | you 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
|
---|
736 | the OBJECT tag of your web-site. The value can point to the server
|
---|
737 | file 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
|
---|
740 | ActiveX and COM programming as well as in the MSDN library and various
|
---|
741 | other Online resources. The examples include INF files that can be used
|
---|
742 | to 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
|
---|
759 | are listed in the INF files. To distribute an ActiveX server depending on
|
---|
760 | DLLs you must add the dependencies, and provide the library files
|
---|
761 | with 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
|
---|
765 | the <tt><object></tt> HTML tag.
|
---|
766 | <p> <pre>
|
---|
767 | <object ID="MyActiveX1" CLASSID="CLSID:ad90301a-849e-4e8b-9a91-0a6dc5f6461f">
|
---|
768 | ...
|
---|
769 | <\object>
|
---|
770 | </pre>
|
---|
771 |
|
---|
772 | <p> To initialize the control's properties, use
|
---|
773 | <pre>
|
---|
774 | <object ID=...>
|
---|
775 | <param name="name" value="value">
|
---|
776 | <\object>
|
---|
777 | </pre>
|
---|
778 |
|
---|
779 | <p> If the web browser supports scripting use JavaScript, VBScript and
|
---|
780 | forms to script the control. The <a href="qaxserver-examples.html">examples</a> include demonstration HTML pages for the
|
---|
781 | example 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
|
---|
785 | controls 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
|
---|
789 | ActiveQt. 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
|
---|
801 | the controls as "Insertable" objects. Reimplement <tt>QAxFactory::registerClass</tt>
|
---|
802 | to add this attribute to the COM class, or set the "Insertable" class info
|
---|
803 | for 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
|
---|
807 | following 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
|
---|
817 | and properties to ActiveX clients, but also those of all super
|
---|
818 | classes, including <a href="qwidget.html">QWidget</a>.
|
---|
819 | <p> This can be controlled by reimplementing <a href="qaxfactory.html">QAxFactory</a>'s
|
---|
820 | exposeToSuperClass() function. Reimplement the function to return
|
---|
821 | the last (furthest up the inheritance hierarchy) super class that
|
---|
822 | should be exposed:
|
---|
823 | <p> <pre>
|
---|
824 | QString MyFactory::exposeToSuperClass( const <a href="qstring.html">QString</a> &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
|
---|
833 | properties to clients, while all other ActiveX controls provided
|
---|
834 | by this factory will expose their own functions and properties and
|
---|
835 | also those of all their super classes including QWidget. The
|
---|
836 | SmallActiveX class can of course propagate some of the QWidget
|
---|
837 | functions 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
|
---|
841 | about how objects are registered or exposed is to provide class
|
---|
842 | specific information using the Q_CLASSINFO macro, which is part of
|
---|
843 | Qt'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.
|
---|
857 | You must reimplement QAxFactory::classID if not specified.
|
---|
858 | <tr bgcolor="#f0f0f0">
|
---|
859 | <td valign="top">InterfaceID
|
---|
860 | <td valign="top">The interface ID.
|
---|
861 | You must reimplement QAxFactory::interfaceID if not specified.
|
---|
862 | <tr bgcolor="#d0d0d0">
|
---|
863 | <td valign="top">EventsID
|
---|
864 | <td valign="top">The event interface ID.
|
---|
865 | No 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.
|
---|
869 | Ie. 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.
|
---|
873 | Ie. 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
|
---|
877 | empty to require a licensed machine. By default classes are not
|
---|
878 | licensed. 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".
|
---|
882 | See <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
|
---|
886 | including the class name in value.
|
---|
887 | See <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"
|
---|
891 | and will be listed in OLE 2 containers (ie. Microsoft Office). This
|
---|
892 | attribute 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
|
---|
896 | default 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,
|
---|
900 | and is only available through the API of another class (ie. the
|
---|
901 | class 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
|
---|
905 | OLE and accessible from the running object table (ie. clients
|
---|
906 | can connect to an already running instance of this class). This
|
---|
907 | attribute 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
|
---|
911 | own API, and is available in the "Insert Objects" dialog of Microsoft
|
---|
912 | Office 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
|
---|
936 | those components. Since the server binary can be shipped to and registered on
|
---|
937 | any client machine it is possible for anybody to use those components in his
|
---|
938 | own software.
|
---|
939 | <p> Licensing components can be done using a variety of techniques, e.g. the code
|
---|
940 | creating the control can provide a license key, or the machine on which the
|
---|
941 | control 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>
|
---|
943 | macro.
|
---|
944 |
|
---|
945 | <pre>
|
---|
946 | class MyLicensedControl : public <a href="qwidget.html">QWidget</a>
|
---|
947 | {
|
---|
948 | Q_OBJECT
|
---|
949 | <b>Q_CLASSINFO("LicenseKey", "<key string>")</b>
|
---|
950 | ...
|
---|
951 | };
|
---|
952 | </pre>
|
---|
953 |
|
---|
954 | The key is required to be able to create an instance of <tt>MyLicensedControl</tt>
|
---|
955 | on a machine that is not licensed itself. The licensed developer can now
|
---|
956 | redistributes the server binary with his application, which creates the control
|
---|
957 | using the value of "LicenseKey", while users of the application cannot create
|
---|
958 | the control without the license key.
|
---|
959 | <p> If a single license key for the control is not sufficient (ie. you want
|
---|
960 | differnet developers to receive different license keys) you can specify an
|
---|
961 | empty 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
|
---|
963 | system (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
|
---|
967 | interfaces to implement the OLE specifications. When the ActiveX class inherits
|
---|
968 | from 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
|
---|
970 | to 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> &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
|
---|
988 | COM interfaces.
|
---|
989 | <p> <pre>
|
---|
990 | long AxImpl::queryInterface( const <a href="quuid.html">QUuid</a> &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
|
---|
1004 | to implement the <tt>QueryInterface</tt>, <tt>AddRef</tt> and <tt>Release</tt> functions.
|
---|
1005 | Use the <tt>QAXAGG_IUNKNOWN</tt> macro in your class definition to do that. If
|
---|
1006 | you implement the IUnknown functions manually, delegate the calls to the
|
---|
1007 | interface pointer returned by the controllingUnknown() function, e.g.
|
---|
1008 | <pre>
|
---|
1009 | HRESULT AxImpl::QueryInterface( REFIID iid, void **iface )
|
---|
1010 | {
|
---|
1011 | return controllingUnknown()->QueryInterface( iid, iface );
|
---|
1012 | }
|
---|
1013 | </pre>
|
---|
1014 |
|
---|
1015 | Do not support the <tt>IUnknown</tt> interface itself in your <tt>queryInterface()</tt>
|
---|
1016 | implementation.
|
---|
1017 | <p> Implement the methods of the COM interfaces, and use QAxAggregated::Object()
|
---|
1018 | if 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
|
---|
1020 | a 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 |
|
---|
1041 | If a standard constructor is not present the compiler will issue
|
---|
1042 | an error "no overloaded function takes 2 parameters" when using
|
---|
1043 | the default factory through the <a href="qaxfactory.html#QAXFACTORY_DEFAULT">QAXFACTORY_DEFAULT</a> macro. If you
|
---|
1044 | cannot provide a standard constructor you must implement a <a href="qaxfactory.html">QAxFactory</a> custom factory and call the constructor you have in
|
---|
1045 | your implementation of QAxFactory::create.
|
---|
1046 | <a href="#footnote-call1">Back...</a> <li><a name="footnote2"></a>
|
---|
1047 |
|
---|
1048 | COM cannot marshal IPictureDisp accross process boundaries,
|
---|
1049 | so <a href="qpixmap.html">QPixmap</a> properties cannot be called for out-of-process servers. You
|
---|
1050 | can however marshal the image data via e.g. temporary files. See the
|
---|
1051 | Microsoft
|
---|
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 |
|
---|
1056 | OLE needs to marshal user defined types by reference (ByRef), and cannot
|
---|
1057 | marshal them by value (ByVal). This is why const-references and object
|
---|
1058 | parameters 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
|
---|
1059 | servers 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 |
|
---|
1062 | This is not required, but gives the client more control over
|
---|
1063 | the 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 © 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>
|
---|