You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1074 lines
42 KiB
1074 lines
42 KiB
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/extensions/activeqt/doc/control.doc:1 -->
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>The TQAxServer Module</title>
|
|
<style type="text/css"><!--
|
|
fn { margin-left: 1cm; text-indent: -1cm; }
|
|
a:link { color: #004faf; text-decoration: none }
|
|
a:visited { color: #672967; text-decoration: none }
|
|
body { background: #ffffff; color: black; }
|
|
--></style>
|
|
</head>
|
|
<body>
|
|
|
|
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
|
<tr bgcolor="#E5E5E5">
|
|
<td valign=center>
|
|
<a href="index.html">
|
|
<font color="#004faf">Home</font></a>
|
|
| <a href="classes.html">
|
|
<font color="#004faf">All Classes</font></a>
|
|
| <a href="mainclasses.html">
|
|
<font color="#004faf">Main Classes</font></a>
|
|
| <a href="annotated.html">
|
|
<font color="#004faf">Annotated</font></a>
|
|
| <a href="groups.html">
|
|
<font color="#004faf">Grouped Classes</font></a>
|
|
| <a href="functions.html">
|
|
<font color="#004faf">Functions</font></a>
|
|
</td>
|
|
<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>The TQAxServer Module</h1>
|
|
|
|
|
|
<p>
|
|
<p> <!-- toc -->
|
|
<ul>
|
|
<li><a href="#1"> Introduction
|
|
</a>
|
|
<li><a href="#2"> Building the library
|
|
</a>
|
|
<li><a href="#3"> Using the library
|
|
</a>
|
|
<ul>
|
|
<li><a href="#3-1"> Out-of-process vs. In-process
|
|
</a>
|
|
</ul>
|
|
<li><a href="#4"> The TQAxServer build system
|
|
</a>
|
|
<ul>
|
|
<li><a href="#4-1"> Typical build problems
|
|
</a>
|
|
<ul>
|
|
<li><a href="#4-1-1"> Compiler errors
|
|
</a>
|
|
<ul>
|
|
<li><a href="#4-1-1-1"> "No overloaded function takes 2 parameters"
|
|
</a>
|
|
<li><a href="#4-1-1-2"> "syntax error: bad suffix on number"
|
|
</a>
|
|
</ul>
|
|
<li><a href="#4-1-2"> Linker errors
|
|
</a>
|
|
<ul>
|
|
<li><a href="#4-1-2-1"> "unresolved external symbol _ucm_instantiate"
|
|
</a>
|
|
<li><a href="#4-1-2-2"> "_ucm_initialize already defined in ..."
|
|
</a>
|
|
<li><a href="#4-1-2-3"> "cannot open file ... "
|
|
</a>
|
|
</ul>
|
|
<li><a href="#4-1-3"> Postprocessing and runtime errors
|
|
</a>
|
|
<ul>
|
|
<li><a href="#4-1-3-1"> The server executable crashes
|
|
</a>
|
|
<li><a href="#4-1-3-2"> The server executable is not a valid Win32 application
|
|
</a>
|
|
<li><a href="#4-1-3-3"> "Unable to Locate DLL"
|
|
</a>
|
|
<li><a href="#4-1-3-4"> The Server does not respond
|
|
</a>
|
|
<li><a href="#4-1-3-5"> The Object cannot be created
|
|
</a>
|
|
</ul>
|
|
</ul>
|
|
<li><a href="#4-2"> Debugging runtime errors
|
|
</a>
|
|
</ul>
|
|
<li><a href="#5"> Implementing Controls
|
|
</a>
|
|
<ul>
|
|
<li><a href="#5-1"> Data Types
|
|
</a>
|
|
<li><a href="#5-2"> Sub-Objects
|
|
</a>
|
|
<li><a href="#5-3"> Property Notification
|
|
</a>
|
|
</ul>
|
|
<li><a href="#6"> Serving Controls
|
|
</a>
|
|
<ul>
|
|
<li><a href="#6-1"> Distributing TQAxServer binaries
|
|
</a>
|
|
<ul>
|
|
<li><a href="#6-1-1"> Installing stand-alone Servers
|
|
</a>
|
|
<li><a href="#6-1-2"> Installing In-process Servers
|
|
</a>
|
|
<li><a href="#6-1-3"> Distributing Servers over the Internet
|
|
</a>
|
|
</ul>
|
|
</ul>
|
|
<li><a href="#7"> Using the Controls
|
|
</a>
|
|
<ul>
|
|
<li><a href="#7-1"> Supported and Unsupported ActiveX clients
|
|
</a>
|
|
<ul>
|
|
<li><a href="#7-1-1"> Supported Clients
|
|
</a>
|
|
<li><a href="#7-1-2"> Unsupported Clients
|
|
</a>
|
|
</ul>
|
|
</ul>
|
|
<li><a href="#8"> Enhanced features
|
|
</a>
|
|
<ul>
|
|
<li><a href="#8-1"> Fewer methods and properties
|
|
</a>
|
|
<li><a href="#8-2"> Class Information and Tuning
|
|
</a>
|
|
<li><a href="#8-3"> Developing licensed components
|
|
</a>
|
|
<li><a href="#8-4"> More Interfaces
|
|
</a>
|
|
</ul>
|
|
</ul>
|
|
<!-- endtoc -->
|
|
|
|
<p> <h2> Introduction
|
|
</h2>
|
|
<a name="1"></a><p> The TQAxServer module provides a static library implementing the
|
|
functions required to turn a standard TQt binary into an ActiveX
|
|
control server.
|
|
<p> This module is part of the <a href="activentqt.html">ActiveTQt
|
|
framework</a>. (To incorporate ActiveX controls in a TQt
|
|
application see the <a href="qaxcontainer.html">TQAxContainer
|
|
module</a>.)
|
|
<p> The module consists of three classes
|
|
<ul>
|
|
<li> <a href="qaxfactory.html">TQAxFactory</a> defines a factory for the creation of ActiveX components.
|
|
<li> <a href="qaxbindable.html">TQAxBindable</a> provides an interface between the TQt widget and the
|
|
ActiveX control.
|
|
<li> <a href="qaxaggregated.html">TQAxAggregated</a> can be subclassed to implement additional COM interfaces.
|
|
</ul>
|
|
<p> Some <a href="qaxserver-examples.html">example implementations</a>
|
|
of ActiveX controls are provided.
|
|
<p> <h2> Building the library
|
|
</h2>
|
|
<a name="2"></a><p> In the <tt>activeqt</tt> directory (usually <tt>QTDIR/extensions/activeqt</tt>)
|
|
enter the <tt>control</tt> subdirectory and run <tt>qmake</tt> to generate the
|
|
makefile, and use the make tool (<tt>nmake</tt> for VC++, <tt>make</tt> for Borland)
|
|
to build the library. The library <tt>qaxserver.lib</tt> will be linked into
|
|
<tt>QTDIR/lib</tt>.
|
|
<p> <h2> Using the library
|
|
</h2>
|
|
<a name="3"></a><p> To turn a standard TQt application into an ActiveX server using the
|
|
TQAxServer library you must add <tt>activeqt</tt> as a CONFIG setting
|
|
in your <tt>.pro</tt> file.
|
|
<p> An out-of-process executable server is generated from a <tt>.pro</tt>
|
|
file like this:
|
|
<pre>
|
|
TEMPLATE = app
|
|
CONFIG += qt activeqt
|
|
|
|
RC_FILE = qaxserver.rc
|
|
...
|
|
</pre>
|
|
|
|
<p> To build an in-process server, use a <tt>.pro</tt> file like this:
|
|
<pre>
|
|
TEMPLATE = lib
|
|
CONFIG += qt activeqt dll
|
|
|
|
DEF_FILE = qaxserver.def
|
|
RC_FILE = qaxserver.rc
|
|
...
|
|
</pre>
|
|
|
|
<p> The files <tt>qaxserver.rc</tt> and <tt>qaxserver.def</tt> are part of the
|
|
framework and can be used from their usual location (specify a
|
|
path in the <tt>.pro</tt> file), or copied into the project directory.
|
|
You can modify these files as long as it includes any file as the
|
|
type library entry, ie. you can add version information or use a
|
|
different toolbox icon.
|
|
<p> The <tt>activeqt</tt> configuration will cause the <tt>qmake</tt> tool to add the
|
|
required build steps to the build system:
|
|
<ul>
|
|
<li> link the binary against <tt>qaxserver.lib</tt>
|
|
<li> generate an interface definition and link the type library into
|
|
the binary
|
|
<li> register the server
|
|
</ul>
|
|
<p> Additionally you can specify a version number using the <tt>VERSION</tt>
|
|
variable, e.g.
|
|
<pre>
|
|
TEMPLATE = lib
|
|
VERSION = 2.5
|
|
...
|
|
</pre>
|
|
|
|
The version number specified will be used as the version of the type
|
|
library and of the server when registering.
|
|
<p> <h3> Out-of-process vs. In-process
|
|
</h3>
|
|
<a name="3-1"></a><p> Whether your ActiveX server should run as a stand-alone executable
|
|
or as a shared library in the client process depends mainly on the
|
|
type of controls you want to provide in the server.
|
|
<p> An executable server has the advantage of being able to run as a
|
|
stand-alone application, but adds considerable overhead to the
|
|
communication between the ActiveX client and the control. If the
|
|
control has a programming error only the server process running
|
|
the control will crash, and the client application will probably
|
|
continue to run.
|
|
<p> An in-process server is usually smaller and has faster startup
|
|
time. The communication between client and server is done directly
|
|
through virtual function calls and does not introduce the overhead
|
|
required for remote procedure calls. But if the server crashes the
|
|
client application is likely to crash as well.
|
|
<p> Both server types can use TQt either as a shared library, or
|
|
statically linked into the server binary.
|
|
<p> <h2> The TQAxServer build system
|
|
</h2>
|
|
<a name="4"></a><p> To be able to build ActiveX controls with TQt, the build system
|
|
must be extended to include some additional build steps that are
|
|
used when the <tt>.pro</tt> file includes <tt>activeqt</tt> in the <tt>CONFIG</tt>
|
|
settings. The resulting makefile will:
|
|
<p> <ul>
|
|
<li> Link the executable against <tt>qaxserver.lib</tt> instead of <tt>qtmain.lib</tt>
|
|
<li> Call the resulting executable with the <tt>-dumpidl</tt> parameter to
|
|
generate an IDL description of the ActiveX controls provided by
|
|
the server.
|
|
<li> Compile the IDL into a type library using the MIDL tool
|
|
<li> Attach the resulting type library as a binary resource to the server
|
|
executable
|
|
</ul>
|
|
<p> Attaching resources to an executable is not supported by
|
|
Windows 95/98/ME, but a server built on
|
|
Windows NT/2000/XP will work on those versions.
|
|
<p> <h3> Typical build problems
|
|
</h3>
|
|
<a name="4-1"></a><p> The compiler/linker errors listed are based on those issued by the
|
|
Microsoft Visual C++ 6.0 compiler.
|
|
<p> <h4> Compiler errors
|
|
</h4>
|
|
<a name="4-1-1"></a><p> <h5> "No overloaded function takes 2 parameters"
|
|
</h5>
|
|
<a name="4-1-1-1"></a><p> When the error occurs in code that uses the <a href="qaxfactory.html#TQAXFACTORY_DEFAULT">TQAXFACTORY_DEFAULT</a>
|
|
macro, the widget class had no constructor that can be used by the
|
|
default factory. Either add a standard widget constructor or
|
|
implement a custom factory that doesn't require one.
|
|
<p> When the error occurs in code that uses the <a href="qaxfactory.html#TQAXFACTORY_EXPORT">TQAXFACTORY_EXPORT</a>
|
|
macro, the <a href="qaxfactory.html">TQAxFactory</a> subclass had no appropriate constructor.
|
|
Provide a public class constructor like
|
|
<pre>
|
|
MyFactory( const <a href="ntquuid.html">TQUuid</a> &, const <a href="ntquuid.html">TQUuid</a> & );
|
|
</pre>
|
|
|
|
for your factory class.
|
|
<p> <h5> "syntax error: bad suffix on number"
|
|
</h5>
|
|
<a name="4-1-1-2"></a><p> The unique identifiers have not been passed as strings into the
|
|
<a href="qaxfactory.html#TQAXFACTORY_EXPORT">TQAXFACTORY_EXPORT</a> or <a href="qaxfactory.html#TQAXFACTORY_DEFAULT">TQAXFACTORY_DEFAULT</a> macro.
|
|
<p> <h4> Linker errors
|
|
</h4>
|
|
<a name="4-1-2"></a><p> <h5> "unresolved external symbol _ucm_instantiate"
|
|
</h5>
|
|
<a name="4-1-2-1"></a><p> The server does not export an implementation of a TQAxFactory. Use
|
|
the <a href="qaxfactory.html#TQAXFACTORY_EXPORT">TQAXFACTORY_EXPORT</a> macro in one of the project's
|
|
implementation files to instantiate and export a factory, or use
|
|
the <a href="qaxfactory.html#TQAXFACTORY_DEFAULT">TQAXFACTORY_DEFAULT</a> macro to use the default factory.
|
|
<p> <h5> "_ucm_initialize already defined in ..."
|
|
</h5>
|
|
<a name="4-1-2-2"></a><p> The server exports more than one implementation of a <a href="qaxfactory.html">TQAxFactory</a>,
|
|
or exports the same implementation twice. If you use the default
|
|
factory, the <a href="qaxfactory.html#TQAXFACTORY_DEFAULT">TQAXFACTORY_DEFAULT</a> macro must only be used once in
|
|
the project. Use a custom TQAxFactory implementation and the <a href="qaxfactory.html#TQAXFACTORY_EXPORT">TQAXFACTORY_EXPORT</a> macro if the server provides multiple ActiveX
|
|
controls.
|
|
<p> <h5> "cannot open file ... "
|
|
</h5>
|
|
<a name="4-1-2-3"></a><p> The ActiveX server could not shut down properly when the last
|
|
client stopped using it. It usually takes about two seconds for
|
|
the application to terminate, but you might have to use the task
|
|
manager to kill the process (e.g. when a client doesn't release
|
|
the controls properly).
|
|
<p> <h4> Postprocessing and runtime errors
|
|
</h4>
|
|
<a name="4-1-3"></a><p> The <a href="activentqt.html#ActiveTQt">ActiveTQt</a> build system performs four commands after the linking
|
|
of the binary to make it into an ActiveX server.
|
|
<p> <ul>
|
|
<li> Call the server to dump the IDL for the controls
|
|
<li> Compile the IDL into a type library
|
|
<li> Attach the type library as a binary resource to the server
|
|
<li> Register the server
|
|
</ul>
|
|
<p> For this to work the server has to meet some requirements:
|
|
<p> <ul>
|
|
<li> All controls exposed can be created with nothing but a <a href="ntqapplication.html">TQApplication</a>
|
|
instance being present
|
|
<li> The initial linking of the server includes a temporary type
|
|
library resource
|
|
<li> All dependencies required to run the server are in the system path
|
|
(or in the path used by the calling environment; note that Visual
|
|
Studio has it's own set of environment variables listed in the
|
|
Tools|Options|Directories dialog).
|
|
</ul>
|
|
<p> If those requirements are not met one ore more of the following
|
|
errors are likely to occure:
|
|
<p> <h5> The server executable crashes
|
|
</h5>
|
|
<a name="4-1-3-1"></a><p> To generate the IDL the widgets exposed as ActiveX controls need to
|
|
be instantiated (the constructor is called). At this point, nothing
|
|
else but a TQApplication object exists. Your widget constructor must
|
|
not rely on any other objects to be created, e.g. it should check for
|
|
null-pointers.
|
|
<p> To debug your server run it with -dumpidl outputfile and check where
|
|
it crashes.
|
|
<p> Note that no functions of the control are called.
|
|
<p> <h5> The server executable is not a valid Win32 application
|
|
</h5>
|
|
<a name="4-1-3-2"></a><p> Attaching the type library corrupted the server binary. This is a
|
|
bug in Windows and happens only with release builds.
|
|
<p> The first linking step has to link a dummy type library into the
|
|
executable that can later be replaced by idc. Add a resource file
|
|
with a type library to your project as demonstrated in the examples.
|
|
<p> <h5> "Unable to Locate DLL"
|
|
</h5>
|
|
<a name="4-1-3-3"></a><p> The build system needs to run the server executable to generate
|
|
the interface definition, and to register the server. If a dynamic
|
|
link library the server links against is not in the path this
|
|
might fail (e.g. Visual Studio calls the server using the
|
|
enivronment settings specified in the "Directories" option). Make
|
|
sure that all DLLs required by your server are located in a
|
|
directory that is listed in the path as printed in the error
|
|
message box.
|
|
<p> <h5> The Server does not respond
|
|
</h5>
|
|
<a name="4-1-3-4"></a><p> If the system is unable to start the server (check with the task
|
|
manager whether the server runs a process), make sure that no DLL
|
|
the server depends on is missing from the system path (e.g. the TQt
|
|
DLL!). Use a dependency walker to view all dependencies of the server
|
|
binary.
|
|
<p> If the server runs (e.g. the task manager lists a process), see
|
|
the following section for information on debugging your server.
|
|
<p> <h5> The Object cannot be created
|
|
</h5>
|
|
<a name="4-1-3-5"></a><p> If the server could be built and registered correctly during the build
|
|
process, but the object cannot be initiliazed e.g. by the OLE/COM Object
|
|
Viewer application, make sure that no DLL the server depends on is
|
|
missing from the system path (e.g. the TQt DLL). Use a dependency walker
|
|
to view all dependencies of the server binary.
|
|
<p> If the server runs, see the following section for information on
|
|
debugging your server.
|
|
<p> <h3> Debugging runtime errors
|
|
</h3>
|
|
<a name="4-2"></a><p> To debug an in-process server in Visual Studio, set the server project
|
|
as the active project, and specify a client "executable for debug
|
|
session" in the project settings (e.g. use the ActiveX Test Container).
|
|
You can set breakpoints in your code, and also step into ActiveTQt and
|
|
TQt code if you installed the debug version.
|
|
<p> To debug an executable server, run the application in a debugger
|
|
and start with the command line parameter "-activex". Then start
|
|
your client and create an instance of your ActiveX control. COM
|
|
will use the existing process for the next client trying to create
|
|
an ActiveX control.
|
|
<p> <h2> Implementing Controls
|
|
</h2>
|
|
<a name="5"></a><p> To implement an ActiveX control with TQt, create a subclass of <a href="ntqwidget.html">TQWidget</a>
|
|
or any existing TQWidget subclass:
|
|
<p> <pre>
|
|
#include <<a href="qwidget-h.html">ntqwidget.h</a>>
|
|
|
|
class MyActiveX : public <a href="ntqwidget.html">TQWidget</a>
|
|
{
|
|
<a href="metaobjects.html#TQ_OBJECT">TQ_OBJECT</a>
|
|
</pre>
|
|
|
|
<p> The <a href="metaobjects.html#TQ_OBJECT">TQ_OBJECT</a> macro is required to provide the <a href="metaobjects.html#meta-object">meta object</a> information
|
|
about the widget to the ActiveTQt framework.
|
|
Use the <tt>TQ_PROPERTY</tt> macro to declare properties for the ActiveX control:
|
|
<p> <pre>
|
|
TQ_PROPERTY( int value READ value WRITE setValue )
|
|
</pre>
|
|
|
|
<p> Declare a standard TQWidget constructor taking a parent widget and a name,
|
|
and functions, signals and slots like any normal TQWidget.
|
|
<a href="#footnote1"><sup>(1)</sup></a><a name="footnote-call1"></a>
|
|
<p> <pre>
|
|
public:
|
|
MyActiveX( <a href="ntqwidget.html">TQWidget</a> *parent = 0, const char *name = 0 )
|
|
...
|
|
|
|
int value() const;
|
|
|
|
public slots:
|
|
void setValue( int );
|
|
...
|
|
|
|
signals:
|
|
void valueChange( int );
|
|
...
|
|
|
|
};
|
|
</pre>
|
|
|
|
<p> The ActiveTQt framework will expose properties and public slots as ActiveX
|
|
properties and methods, and signals as ActiveX events, and convert between
|
|
the TQt data types and the equivalent COM data types.
|
|
<p> <h3> Data Types
|
|
</h3>
|
|
<a name="5-1"></a><p> The TQt data types that are supported for properties are:
|
|
<p> <center><table cellpadding="4" cellspacing="2" border="0">
|
|
<tr bgcolor="#a2c511">
|
|
<th valign="top">TQt data type
|
|
<th valign="top">COM property
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">bool
|
|
<td valign="top">VARIANT_BOOL
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQString
|
|
<td valign="top">BSTR
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQCString
|
|
<td valign="top">BSTR
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">int
|
|
<td valign="top">int
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">uint
|
|
<td valign="top">unsigned int
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">double
|
|
<td valign="top">double
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQ_LLONG
|
|
<td valign="top">CY
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQ_ULLONG
|
|
<td valign="top">CY
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQColor
|
|
<td valign="top">OLE_COLOR
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQDate
|
|
<td valign="top">DATE
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQDateTime
|
|
<td valign="top">DATE
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQTime
|
|
<td valign="top">DATE
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQFont
|
|
<td valign="top">IFontDisp*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQPixmap
|
|
<td valign="top">IPictureDisp*
|
|
<a href="#footnote2"><sup>(2)</sup></a><a name="footnote-call2"></a>
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQVariant
|
|
<td valign="top">VARIANT
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQValueList<TQVariant>
|
|
<td valign="top">SAFEARRAY(VARIANT)
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQStringList
|
|
<td valign="top">SAFEARRAY(BSTR)
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQByteArray
|
|
<td valign="top">SAFEARRAY(BYTE)
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQRect
|
|
<td valign="top">User defined type
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQSize
|
|
<td valign="top">User defined type
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQPoint
|
|
<td valign="top">User defined type
|
|
</table></center>
|
|
<p> The TQt data types that are supported for parameters in signals and
|
|
slots are:
|
|
<center><table cellpadding="4" cellspacing="2" border="0">
|
|
<tr bgcolor="#a2c511">
|
|
<th valign="top">TQt data type
|
|
<th valign="top">COM parameter
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">bool
|
|
<td valign="top">[in] VARIANT_BOOL
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">bool&
|
|
<td valign="top">[in, out] VARIANT_BOOL*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQString, const <a href="ntqstring.html">TQString</a>&
|
|
<td valign="top">[in] BSTR
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQString&
|
|
<td valign="top">[in, out] BSTR*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQCString, const <a href="ntqcstring.html">TQCString</a>&
|
|
<td valign="top">[in] BSTR
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQString&
|
|
<td valign="top">[in, out] BSTR*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">int
|
|
<td valign="top">[in] int
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">int&
|
|
<td valign="top">[in,out] int
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">uint
|
|
<td valign="top">[in] unsigned int
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">uint&
|
|
<td valign="top">[in, out] unsigned int*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">double
|
|
<td valign="top">[in] double
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">double&
|
|
<td valign="top">[in, out] double*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQColor, const <a href="ntqcolor.html">TQColor</a>&
|
|
<td valign="top">[in] OLE_COLOR
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQColor&
|
|
<td valign="top">[in, out] OLE_COLOR*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQDate, const <a href="qdate.html">TQDate</a>&
|
|
<td valign="top">[in] DATE
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQDate&
|
|
<td valign="top">[in, out] DATE*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQDateTime, const <a href="ntqdatetime.html">TQDateTime</a>&
|
|
<td valign="top">[in] DATE
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQDateTime&
|
|
<td valign="top">[in, out] DATE*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQFont, const <a href="ntqfont.html">TQFont</a>&
|
|
<td valign="top">[in] IFontDisp*
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQFont&
|
|
<td valign="top">[in, out] IFontDisp**
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQPixmap, const <a href="ntqpixmap.html">TQPixmap</a>&
|
|
<td valign="top">[in] IPictureDisp*
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQPixmap&
|
|
<td valign="top">[in, out] IPictureDisp**
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQValueList<TQVariant>, const <a href="ntqvaluelist.html">TQValueList</a><TQVariant>&
|
|
<td valign="top">[in] SAFEARRAY(VARIANT)
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQValueList<TQVariant>&
|
|
<td valign="top">[in, out] SAFEARRAY(VARIANT)*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQStringList, const <a href="ntqstringlist.html">TQStringList</a>&
|
|
<td valign="top">[in] SAFEARRAY(BSTR)
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQStringList&
|
|
<td valign="top">[in, out] SAFEARRAY(BSTR)*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQByteArray, const <a href="qbytearray.html">TQByteArray</a>&
|
|
<td valign="top">[in] SAFEARRAY(BYTE)
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQByteArray&
|
|
<td valign="top">[in, out] SAFEARRAY(BYTE)*
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQObject*
|
|
<td valign="top">[in] IDispatch*
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQRect&
|
|
<a href="#footnote3"><sup>(3)</sup></a><a name="footnote-call3"></a>
|
|
<td valign="top">[in, out] struct <a href="ntqrect.html">TQRect</a> (user defined)
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">TQSize&
|
|
<td valign="top">[in, out] struct <a href="ntqsize.html">TQSize</a> (user defined)
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">TQPoint&
|
|
<td valign="top">[in, out] struct <a href="ntqpoint.html">TQPoint</a> (user defined)
|
|
</table></center>
|
|
<p> Also supported are exported enums and sets (see TQ_ENUMS and TQ_SETS).
|
|
The in-parameter types are also supported as return values.
|
|
<p> Properties and signals/slots that have parameters using any other
|
|
data types are ignored by the TQActiveX framework.
|
|
<p> <h3> Sub-Objects
|
|
</h3>
|
|
<a name="5-2"></a><p> COM objects can have multiple sub-objects that can represent a sub element
|
|
of the COM object. A COM object representing a multi-document spread sheet
|
|
application can for example provide one sub-object for each spread sheet.
|
|
<p> Any <a href="ntqobject.html">TQObject</a> subclass can be used as the type for a sub object in ActiveX. The
|
|
<a href="qaxfactory.html">TQAxFactory</a> implementation (see below) needs to return the classname of the
|
|
sub type as one key in the featureList() implementation, as well as the IDs
|
|
for the COM class, the interface and event interface of that type. Then the
|
|
type can be used as e.g. the return value or paramter of a slot.
|
|
<p> <h3> Property Notification
|
|
</h3>
|
|
<a name="5-3"></a><p> To make the properties bindable for the ActiveX client, use multiple
|
|
inheritance from the <a href="qaxbindable.html">TQAxBindable</a> class:
|
|
<p>
|
|
<pre>
|
|
#include <ntqwidget.h>
|
|
<b>#include <qaxbindable.h></b>
|
|
|
|
class MyActiveX : public <a href="ntqwidget.html">TQWidget</a><b>, public TQAxBindable</b>
|
|
{
|
|
TQ_OBJECT
|
|
</pre>
|
|
|
|
When implementing the property write functions, use the
|
|
TQAxBindable class's requestPropertyChange() and propertyChanged()
|
|
functions to allow ActiveX clients to bind to the control
|
|
properties.
|
|
<a href="#footnote4"><sup>(4)</sup></a><a name="footnote-call4"></a>
|
|
<p> <h2> Serving Controls
|
|
</h2>
|
|
<a name="6"></a><p> To make an ActiveX control available to the COM system it must
|
|
be registered in the system registry using five unique
|
|
identifiers. These identifiers are provided by tools like <tt>guidgen</tt> or <tt>uuidgen</tt>. The registration information allows COM to
|
|
localize the binary providing a requested ActiveX control,
|
|
marshall remote procedure calls to the control and read type
|
|
information about the methods and properties exposed by the
|
|
control.
|
|
<p> To create the ActiveX control when the client asks for it the
|
|
server must export an implementation of a <a href="qaxfactory.html">TQAxFactory</a>. Use the
|
|
default factory when the server provides only a single ActiveX
|
|
control, and implement a subclass of TQAxFactory to provide
|
|
multiple ActiveX controls. The default factory is available
|
|
through a macro that takes the identifiers COM requires to locate
|
|
the ActiveX control on the target system:
|
|
<p> <pre>
|
|
TQAXFACTORY_DEFAULT ( MyActiveX,
|
|
"{ad90301a-849e-4e8b-9a91-0a6dc5f6461f}",
|
|
"{87a5b65e-7fa9-4dc6-a176-47295988dcbd}",
|
|
"{a6130ae9-8327-47ec-815b-d0b45a0d6e5e}",
|
|
"{26c4e136-4e23-4347-af37-faf933b027e9}",
|
|
"{a8f21901-7ff7-4f6a-b939-789620c03d83}" )
|
|
</pre>
|
|
|
|
<p> The <a href="qaxfactory.html">TQAxFactory class documentation</a> explains
|
|
how to use this macro, and how to implement and use custom factories.
|
|
<p> For out-of-process executable servers you can implement a main()
|
|
function to instantiate a <a href="ntqapplication.html">TQApplication</a> object and enter the event
|
|
loop just like any normal TQt application. By default the
|
|
application will start as a standard TQt application, but if you
|
|
pass <tt>-activex</tt> on the command line it will start as an ActiveX
|
|
server. Use <a href="qaxfactory.html#isServer">TQAxFactory::isServer</a>() to create and run a standard
|
|
application interface, or to prevent a stand-alone execution:
|
|
<p>
|
|
<pre>
|
|
#include <ntqapplication.h>
|
|
<b>#include <qaxfactory.h></b>
|
|
|
|
int main( int argc, char **argv )
|
|
{
|
|
TQApplication app( argc, argv );
|
|
<b>if ( !TQAxFactory::isServer() ) {
|
|
// create and show main window...
|
|
}</b>
|
|
return app.exec();
|
|
}
|
|
</pre>
|
|
|
|
This is however not necessary as ActiveTQt provides a default implementation
|
|
of a main function. The default implemenation calls <a href="qaxfactory.html#startServer">TQAxFactory::startServer</a>(),
|
|
creates a TQApplication instance and calls exec().
|
|
<p> To build the ActiveX server executable run <a href="qmake-manual.html">qmake</a> to generate the makefile, and use your compiler's
|
|
make tool as for any other TQt application. The make process will
|
|
also register the controls in the system registry by calling the
|
|
resulting executable with the <tt>-regserver</tt> command line option.
|
|
<p> If the ActiveX server is an executable, the following command line
|
|
options are supported:
|
|
<center><table cellpadding="4" cellspacing="2" border="0">
|
|
<tr bgcolor="#a2c511"> <th valign="top">Option <th valign="top">Result
|
|
<tr bgcolor="#d0d0d0"> <td valign="top"><tt>-regserver</tt> <td valign="top">Registers the server in the system registry
|
|
<tr bgcolor="#f0f0f0"> <td valign="top"><tt>-unregserver</tt> <td valign="top">Unregisters the server from the system registry
|
|
<tr bgcolor="#d0d0d0"> <td valign="top"><tt>-activex</tt> <td valign="top">Starts the application as an ActiveX server
|
|
<tr bgcolor="#f0f0f0"> <td valign="top"><tt>-dumpidl <file> -version x.y</tt> <td valign="top">Writes the server's IDL to the
|
|
specified file. The type library will have version x.y
|
|
</table></center>
|
|
<p> In-process servers can be registered using the <tt>regsvr32</tt> tool available
|
|
on all Windows systems.
|
|
<p> <h3> Distributing TQAxServer binaries
|
|
</h3>
|
|
<a name="6-1"></a><p> ActiveX servers written with TQt can use TQt either as a shared
|
|
library, or have TQt linked statically into the binary. Both ways
|
|
will produce rather large packages (either the server binary
|
|
itself becomes large, or you have to ship the TQt DLL).
|
|
<p> <h4> Installing stand-alone Servers
|
|
</h4>
|
|
<a name="6-1-1"></a><p> When your ActiveX server can also run as a stand-alone application,
|
|
run the server executable with the <tt>-regserver</tt> command line
|
|
parameter after installing the executable on the target system.
|
|
After that the controls provided by the server will be available to
|
|
ActiveX clients.
|
|
<p> <h4> Installing In-process Servers
|
|
</h4>
|
|
<a name="6-1-2"></a><p> When your ActiveX server is part of an installation package, use the
|
|
<tt>regsvr32</tt> tool provided by Microsoft to register the controls on
|
|
the target system. If this tool is not present, load the DLL into
|
|
your installer process, resolve the <tt>DllRegisterServer</tt> symbol and
|
|
call the function:
|
|
<p> <pre>
|
|
HMODULE dll = LoadLibrary( "myserver.dll" );
|
|
typedef HRESULT(__stdcall *DllRegisterServerProc)();
|
|
DllRegisterServerProc DllRegisterServer =
|
|
(DllRegisterServerProc)GetProcAddress( dll, "DllRegisterServer" );
|
|
|
|
HRESULT res = E_FAIL;
|
|
if ( DllRegisterServer )
|
|
res = DllRegisterServer();
|
|
if ( res != S_OK )
|
|
// error handling
|
|
</pre>
|
|
|
|
<p> <h4> Distributing Servers over the Internet
|
|
</h4>
|
|
<a name="6-1-3"></a><p> If you want to use controls in your server in web-pages you need to
|
|
make the server available to the browser used to view your page, and
|
|
you need to specify the location of the server package in your page.
|
|
<p> To specify the location of a server, use the CODEBASE attribute in
|
|
the OBJECT tag of your web-site. The value can point to the server
|
|
file itself, to an <tt>INF</tt> file listing other files the server requires
|
|
(e.g. the TQt DLL), or a compressed <tt>CAB</tt> archive.
|
|
<p> INF and CAB files are documented in almost every book available about
|
|
ActiveX and COM programming as well as in the MSDN library and various
|
|
other Online resources. The examples include INF files that can be used
|
|
to build CAB archives:
|
|
<p>
|
|
|
|
<pre> [version]
|
|
signature="$CHICAGO$"
|
|
AdvancedINF=2.0
|
|
[Add.Code]
|
|
simpleax.exe=simpleax.exe
|
|
[simpleax.exe]
|
|
file-win32-x86=thiscab
|
|
clsid={DF16845C-92CD-4AAB-A982-EB9840E74669}
|
|
RegisterServer=yes
|
|
</pre>
|
|
<p> The CABARC tool from Microsoft can easily generate CAB archives:
|
|
<pre> cabarc N simpleax.cab simpleax.exe simple.inf </pre>
|
|
|
|
<p> The INF files assume a static build of TQt, so no dependencies to other DLLs
|
|
are listed in the INF files. To distribute an ActiveX server depending on
|
|
DLLs you must add the dependencies, and provide the library files
|
|
with the archive.
|
|
<p> <h2> Using the Controls
|
|
</h2>
|
|
<a name="7"></a><p> To use the ActiveX controls, e.g. to embed them in a web page, use
|
|
the <tt><object></tt> HTML tag.
|
|
<p> <pre>
|
|
<object ID="MyActiveX1" CLASSID="CLSID:ad90301a-849e-4e8b-9a91-0a6dc5f6461f">
|
|
...
|
|
<\object>
|
|
</pre>
|
|
|
|
<p> To initialize the control's properties, use
|
|
<pre>
|
|
<object ID=...>
|
|
<param name="name" value="value">
|
|
<\object>
|
|
</pre>
|
|
|
|
<p> If the web browser supports scripting use JavaScript, VBScript and
|
|
forms to script the control. The <a href="qaxserver-examples.html">examples</a> include demonstration HTML pages for the
|
|
example controls.
|
|
<p> <h3> Supported and Unsupported ActiveX clients
|
|
</h3>
|
|
<a name="7-1"></a><p> The following is largly based on our own experiements with ActiveX
|
|
controls and client applications, and is by no means complete.
|
|
<p> <h4> Supported Clients
|
|
</h4>
|
|
<a name="7-1-1"></a><p> These standard applications work with ActiveX controls developed with
|
|
ActiveTQt. Note that some clients support only in-process controls.
|
|
<p> <ul>
|
|
<li> Internet Explorer
|
|
<li> Microsoft ActiveX Control Test Container
|
|
<li> Microsoft Visual Studio 6.0
|
|
<li> Microsoft Visual Studio.NET/2003
|
|
<li> Microsoft Visual Basic 6.0
|
|
<li> MFC- and ATL-based containers
|
|
<li> Sybase PowerBuilder
|
|
<li> ActiveTQt based containers
|
|
</ul>
|
|
<p> Microsoft Office applications are supported, but you need to register
|
|
the controls as "Insertable" objects. Reimplement <tt>TQAxFactory::registerClass</tt>
|
|
to add this attribute to the COM class, or set the "Insertable" class info
|
|
for your class to "yes" using the TQ_CLASSINFO macro.
|
|
<p> <h4> Unsupported Clients
|
|
</h4>
|
|
<a name="7-1-2"></a><p> We have not managed to make ActiveTQt based COM objects work with the
|
|
following client applications.
|
|
<p> <ul>
|
|
<li> Borland C++ Builder (Versions 5 and 6)
|
|
<li> Borland Delphi
|
|
</ul>
|
|
<p> <h2> Enhanced features
|
|
</h2>
|
|
<a name="8"></a><p> <h3> Fewer methods and properties
|
|
</h3>
|
|
<a name="8-1"></a><p> By default all ActiveX controls expose not only their own methods
|
|
and properties to ActiveX clients, but also those of all super
|
|
classes, including <a href="ntqwidget.html">TQWidget</a>.
|
|
<p> This can be controlled by reimplementing <a href="qaxfactory.html">TQAxFactory</a>'s
|
|
exposeToSuperClass() function. Reimplement the function to return
|
|
the last (furthest up the inheritance hierarchy) super class that
|
|
should be exposed:
|
|
<p> <pre>
|
|
TQString MyFactory::exposeToSuperClass( const <a href="ntqstring.html">TQString</a> &key ) const
|
|
{
|
|
if ( key == "SmallActiveX" )
|
|
return key;
|
|
return TQAxFactory::exposeToSuperClass( key );
|
|
}
|
|
</pre>
|
|
|
|
<p> The SmallActiveX control will only expose its own functions and
|
|
properties to clients, while all other ActiveX controls provided
|
|
by this factory will expose their own functions and properties and
|
|
also those of all their super classes including TQWidget. The
|
|
SmallActiveX class can of course propagate some of the TQWidget
|
|
functions and properties into its own interface.
|
|
<p> <h3> Class Information and Tuning
|
|
</h3>
|
|
<a name="8-2"></a><p> An alternative way to reimplementing TQAxFactory to have more control
|
|
about how objects are registered or exposed is to provide class
|
|
specific information using the TQ_CLASSINFO macro, which is part of
|
|
TQt's meta object system.
|
|
<p> <center><table cellpadding="4" cellspacing="2" border="0">
|
|
<tr bgcolor="#a2c511">
|
|
<th valign="top">Key
|
|
<th valign="top">Meaning of value
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">Version
|
|
<td valign="top">The version of the class (1.0 is default)
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">Description
|
|
<td valign="top">A string describing the class.
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">ClassID
|
|
<td valign="top">The class ID.
|
|
You must reimplement TQAxFactory::classID if not specified.
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">InterfaceID
|
|
<td valign="top">The interface ID.
|
|
You must reimplement TQAxFactory::interfaceID if not specified.
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">EventsID
|
|
<td valign="top">The event interface ID.
|
|
No signals are exposed as COM events if not specified.
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">DefaultProperty
|
|
<td valign="top">The property specified represents the default property of this class.
|
|
Ie. the default property of a push button would be "text".
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">DefaultSignal
|
|
<td valign="top">The signal specified respresents the default signal of this class.
|
|
Ie. the default signal of a push button would be "clicked".
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">LicenseKey
|
|
<td valign="top">Object creation requires the specified license key. The key can be
|
|
empty to require a licensed machine. By default classes are not
|
|
licensed. Also see the following section.
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">StockEvents
|
|
<td valign="top">Objects expose stock events if value is "yes".
|
|
See <a href="qaxfactory.html#hasStockEvents">TQAxFactory::hasStockEvents</a>()
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">ToSuperClass
|
|
<td valign="top">Objects expose functionality of all super classes up to and
|
|
including the class name in value.
|
|
See <a href="qaxfactory.html#exposeToSuperClass">TQAxFactory::exposeToSuperClass</a>()
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">Insertable
|
|
<td valign="top">If the value is "yes" the class is registered to be "Insertable"
|
|
and will be listed in OLE 2 containers (ie. Microsoft Office). This
|
|
attribute is not be set by default.
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">Aggregatable
|
|
<td valign="top">If the value is "no" the class does not support aggregation. By
|
|
default aggregation is supported.
|
|
<tr bgcolor="#d0d0d0">
|
|
<td valign="top">Creatable
|
|
<td valign="top">If the value is "no" the class cannot be created by the client,
|
|
and is only available through the API of another class (ie. the
|
|
class is a sub-type).
|
|
<tr bgcolor="#f0f0f0">
|
|
<td valign="top">RegisterObject
|
|
<td valign="top">If the value is "yes" objects of this class are registered with
|
|
OLE and accessible from the running object table (ie. clients
|
|
can connect to an already running instance of this class). This
|
|
attribute is only supported in out-of-process servers.
|
|
</table></center>
|
|
<p> Note that both keys and values are case sensitive.
|
|
<p> The following declares version 2.0 of a class that exposes only its
|
|
own API, and is available in the "Insert Objects" dialog of Microsoft
|
|
Office applications.
|
|
<p>
|
|
<pre>
|
|
class MyActiveX : public <a href="ntqwidget.html">TQWidget</a>
|
|
{
|
|
TQ_OBJECT
|
|
<b>TQ_CLASSINFO("Version", "2.0")
|
|
TQ_CLASSINFO("ClassID", "{7a4cffd8-cbcd-4ae9-ae7e-343e1e5710df}")
|
|
TQ_CLASSINFO("InterfaceID", "{6fb035bf-8019-48d8-be51-ef05427d8994}")
|
|
TQ_CLASSINFO("EventsID", "{c42fffdf-6557-47c9-817a-2da2228bc29c}")
|
|
TQ_CLASSINFO("Insertable", "yes")
|
|
TQ_CLASSINFO("ToSuperClass", "MyActiveX")</b>
|
|
|
|
TQ_PROPERTY( ...
|
|
public:
|
|
MyActiveX(TQWidget *parent = 0, const char *name = 0);
|
|
|
|
...
|
|
};
|
|
</pre>
|
|
|
|
<h3> Developing licensed components
|
|
</h3>
|
|
<a name="8-3"></a><p> If you develop components you might want to control who is able to instantiate
|
|
those components. Since the server binary can be shipped to and registered on
|
|
any client machine it is possible for anybody to use those components in his
|
|
own software.
|
|
<p> Licensing components can be done using a variety of techniques, e.g. the code
|
|
creating the control can provide a license key, or the machine on which the
|
|
control is supposed to run needs to be licensed.
|
|
<p> To mark a TQt class as licensed specify a "LicenseKey" using the <tt>TQ_CLASSINFO</tt>
|
|
macro.
|
|
|
|
<pre>
|
|
class MyLicensedControl : public <a href="ntqwidget.html">TQWidget</a>
|
|
{
|
|
TQ_OBJECT
|
|
<b>TQ_CLASSINFO("LicenseKey", "<key string>")</b>
|
|
...
|
|
};
|
|
</pre>
|
|
|
|
The key is required to be able to create an instance of <tt>MyLicensedControl</tt>
|
|
on a machine that is not licensed itself. The licensed developer can now
|
|
redistributes the server binary with his application, which creates the control
|
|
using the value of "LicenseKey", while users of the application cannot create
|
|
the control without the license key.
|
|
<p> If a single license key for the control is not sufficient (ie. you want
|
|
differnet developers to receive different license keys) you can specify an
|
|
empty key to indicate that the control requires a license, and reimplement
|
|
<a href="qaxfactory.html#validateLicenseKey">TQAxFactory::validateLicenseKey</a>() to verify that a license exists on the
|
|
system (ie. through a license file).
|
|
<p> <h3> More Interfaces
|
|
</h3>
|
|
<a name="8-4"></a><p> ActiveX controls provided by ActiveTQt servers support a minimal set of COM
|
|
interfaces to implement the OLE specifications. When the ActiveX class inherits
|
|
from the <a href="qaxbindable.html">TQAxBindable</a> class it can also implement additional COM interfaces.
|
|
<p> Create a new subclass of <a href="qaxaggregated.html">TQAxAggregated</a> and use multiple inheritance
|
|
to subclass additional COM interface classes.
|
|
<p> <pre>
|
|
class AxImpl : public <a href="qaxaggregated.html">TQAxAggregated</a>, public ISomeCOMInterface
|
|
{
|
|
public:
|
|
AxImpl() {}
|
|
|
|
long queryInterface( const <a href="ntquuid.html">TQUuid</a> &iid, void **iface );
|
|
|
|
// IUnknown
|
|
TQAXAGG_IUNKNOWN
|
|
|
|
// ISomeCOMInterface
|
|
...
|
|
}
|
|
</pre>
|
|
|
|
<p> Reimplement the <tt>queryInterface()</tt> function to support the additional
|
|
COM interfaces.
|
|
<p> <pre>
|
|
long AxImpl::queryInterface( const <a href="ntquuid.html">TQUuid</a> &iid, void **iface )
|
|
{
|
|
*iface = 0;
|
|
if ( iid == IID_ISomeCOMInterface )
|
|
*iface = (ISomeCOMInterface*)this;
|
|
else
|
|
return E_NOINTERFACE;
|
|
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
</pre>
|
|
|
|
<p> Since <tt>ISomeCOMInterface</tt> is a subclass of <tt>IUnknown</tt> you will have
|
|
to implement the <tt>QueryInterface</tt>, <tt>AddRef</tt> and <tt>Release</tt> functions.
|
|
Use the <tt>TQAXAGG_IUNKNOWN</tt> macro in your class definition to do that. If
|
|
you implement the IUnknown functions manually, delegate the calls to the
|
|
interface pointer returned by the controllingUnknown() function, e.g.
|
|
<pre>
|
|
HRESULT AxImpl::QueryInterface( REFIID iid, void **iface )
|
|
{
|
|
return controllingUnknown()->QueryInterface( iid, iface );
|
|
}
|
|
</pre>
|
|
|
|
Do not support the <tt>IUnknown</tt> interface itself in your <tt>queryInterface()</tt>
|
|
implementation.
|
|
<p> Implement the methods of the COM interfaces, and use TQAxAggregated::Object()
|
|
if you need to make calls to the <a href="ntqobject.html">TQObject</a> subclass implementing the control.
|
|
<p> In your <a href="qaxbindable.html">TQAxBindable</a> subclass, implement <tt>createAggregate()</tt> to return
|
|
a new object of the <a href="qaxaggregated.html">TQAxAggregated</a> subclass.
|
|
<p>
|
|
<pre>
|
|
class MyActiveX : public <a href="ntqwidget.html">TQWidget</a>,
|
|
<b>public TQAxBindable</b>
|
|
{
|
|
TQ_OBJECT
|
|
public:
|
|
MyActiveX( TQWidget *parent, const char *name = 0 );
|
|
|
|
<b>TQAxAggregated *createAggregate()
|
|
{
|
|
return new AxImpl();
|
|
}
|
|
</b>
|
|
};
|
|
</pre>
|
|
|
|
<hr>
|
|
<ol> <li><a name="footnote1"></a>
|
|
|
|
If a standard constructor is not present the compiler will issue
|
|
an error "no overloaded function takes 2 parameters" when using
|
|
the default factory through the <a href="qaxfactory.html#TQAXFACTORY_DEFAULT">TQAXFACTORY_DEFAULT</a> macro. If you
|
|
cannot provide a standard constructor you must implement a <a href="qaxfactory.html">TQAxFactory</a> custom factory and call the constructor you have in
|
|
your implementation of TQAxFactory::create.
|
|
<a href="#footnote-call1">Back...</a> <li><a name="footnote2"></a>
|
|
|
|
COM cannot marshal IPictureDisp accross process boundaries,
|
|
so <a href="ntqpixmap.html">TQPixmap</a> properties cannot be called for out-of-process servers. You
|
|
can however marshal the image data via e.g. temporary files. See the
|
|
Microsoft
|
|
<a href="http://support.microsoft.com/default.aspx?scid=kb;[LN];Q150034">KB article
|
|
Q150034</a> for more information.
|
|
<a href="#footnote-call2">Back...</a> <li><a name="footnote3"></a>
|
|
|
|
OLE needs to marshal user defined types by reference (ByRef), and cannot
|
|
marshal them by value (ByVal). This is why const-references and object
|
|
parameters are not supported for <a href="ntqrect.html">TQRect</a>, <a href="ntqsize.html">TQSize</a> and <a href="ntqpoint.html">TQPoint</a>. Also note that
|
|
servers with this datatype require Windows 98 or DCOM 1.2 to be installed.
|
|
<a href="#footnote-call3">Back...</a> <li><a name="footnote4"></a>
|
|
|
|
This is not required, but gives the client more control over
|
|
the ActiveX control.
|
|
<a href="#footnote-call4">Back...</a></ol>
|
|
</hr>
|
|
<!-- eof -->
|
|
<p><address><hr><div align=center>
|
|
<table width=100% cellspacing=0 border=0><tr>
|
|
<td>Copyright © 2007
|
|
<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
|
|
<td align=right><div align=right>TQt 3.3.8</div>
|
|
</table></div></address></body>
|
|
</html>
|