src/activeqt/control/qaxfactory.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the ActiveQt framework of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:BSD$
       
    10 ** You may use this file under the terms of the BSD license as follows:
       
    11 **
       
    12 ** "Redistribution and use in source and binary forms, with or without
       
    13 ** modification, are permitted provided that the following conditions are
       
    14 ** met:
       
    15 **   * Redistributions of source code must retain the above copyright
       
    16 **     notice, this list of conditions and the following disclaimer.
       
    17 **   * Redistributions in binary form must reproduce the above copyright
       
    18 **     notice, this list of conditions and the following disclaimer in
       
    19 **     the documentation and/or other materials provided with the
       
    20 **     distribution.
       
    21 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
       
    22 **     the names of its contributors may be used to endorse or promote
       
    23 **     products derived from this software without specific prior written
       
    24 **     permission.
       
    25 **
       
    26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
       
    37 ** $QT_END_LICENSE$
       
    38 **
       
    39 ****************************************************************************/
       
    40 
       
    41 #include "qaxfactory.h"
       
    42 
       
    43 #ifndef QT_NO_WIN_ACTIVEQT
       
    44 
       
    45 #include <qfile.h>
       
    46 #include <qfileinfo.h>
       
    47 #include <qmetaobject.h>
       
    48 #include <qsettings.h>
       
    49 #include <qwidget.h>
       
    50 #include <qt_windows.h>
       
    51 
       
    52 QT_BEGIN_NAMESPACE
       
    53 
       
    54 extern wchar_t qAxModuleFilename[MAX_PATH];
       
    55 
       
    56 /*!
       
    57     \class QAxFactory
       
    58     \brief The QAxFactory class defines a factory for the creation of COM components.
       
    59 
       
    60     \inmodule QAxServer
       
    61 
       
    62     Implement this factory once in your COM server to provide information
       
    63     about the components the server can create. Subclass QAxFactory and implement
       
    64     the pure virtual functions in any implementation file (e.g. main.cpp), and export
       
    65     the factory using the \c QAXFACTORY_EXPORT() macro.
       
    66 
       
    67     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 0
       
    68 
       
    69     If you use the \c Q_CLASSINFO() macro to provide the unique
       
    70     identifiers or other attributes for your class you can use the \c
       
    71     QAXFACTORY_BEGIN(), \c QAXCLASS() and \c QAXFACTORY_END() macros to
       
    72     expose one or more classes as COM objects.
       
    73 
       
    74     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 1
       
    75 
       
    76 
       
    77     If your server supports just a single COM object, you can use
       
    78     a default factory implementation through the \c QAXFACTORY_DEFAULT() macro.
       
    79 
       
    80     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 2
       
    81 
       
    82     Only one QAxFactory implementation may be instantiated and
       
    83     exported by an ActiveX server application. This instance is accessible
       
    84     through the global qAxFactory() function.
       
    85 
       
    86     A factory can also reimplement the registerClass() and
       
    87     unregisterClass() functions to set additional flags for an ActiveX
       
    88     control in the registry. To limit the number of methods or
       
    89     properties a widget class exposes from its parent classes
       
    90     reimplement exposeToSuperClass().
       
    91 
       
    92     \sa QAxAggregated, QAxBindable, {ActiveQt Framework}
       
    93 */
       
    94 
       
    95 /*!
       
    96     Constructs a QAxFactory object that returns \a libid and \a appid
       
    97     in the implementation of the respective interface functions.
       
    98 */
       
    99 
       
   100 QAxFactory::QAxFactory(const QUuid &libid, const QUuid &appid)
       
   101 : typelib(libid), app(appid)
       
   102 {
       
   103 }
       
   104 
       
   105 /*!
       
   106     Destroys the QAxFactory object.
       
   107 */
       
   108 QAxFactory::~QAxFactory()
       
   109 {
       
   110 }
       
   111 
       
   112 /*!
       
   113     \fn QUuid QAxFactory::typeLibID() const
       
   114 
       
   115     Reimplement this function to return the ActiveX server's type
       
   116     library identifier.
       
   117 */
       
   118 QUuid QAxFactory::typeLibID() const
       
   119 {
       
   120     return typelib;
       
   121 }
       
   122 
       
   123 /*!
       
   124     \fn QUuid QAxFactory::appID() const
       
   125 
       
   126     Reimplement this function to return the ActiveX server's
       
   127     application identifier.
       
   128 */
       
   129 QUuid QAxFactory::appID() const
       
   130 {
       
   131     return app;
       
   132 }
       
   133 
       
   134 /*!
       
   135     \fn QStringList QAxFactory::featureList() const
       
   136 
       
   137     Reimplement this function to return a list of the widgets (class
       
   138     names) supported by this factory.
       
   139 */
       
   140 
       
   141 /*!
       
   142     \fn QObject *QAxFactory::createObject(const QString &key)
       
   143 
       
   144     Reimplement this function to return a new object for \a key, or 0 if
       
   145     this factory doesn't support the value of \a key.
       
   146 
       
   147     If the object returned is a QWidget it will be exposed as an ActiveX
       
   148     control, otherwise the returned object will be exposed as a simple COM
       
   149     object.
       
   150 */
       
   151 
       
   152 /*!
       
   153     \fn const QMetaObject *QAxFactory::metaObject(const QString &key) const
       
   154 
       
   155     Reimplement this function to return the QMetaObject corresponding to
       
   156     \a key, or 0 if this factory doesn't support the value of \a key.
       
   157 */
       
   158 
       
   159 /*!
       
   160     \fn bool QAxFactory::createObjectWrapper(QObject *object, IDispatch **wrapper)
       
   161 
       
   162     Reimplement this function to provide the COM object for \a object
       
   163     in \a wrapper. Return true if the function was successful; otherwise
       
   164     return false.
       
   165 
       
   166     The default implementation creates a generic automation wrapper based
       
   167     on the meta object information of \a object.
       
   168 */
       
   169 // implementation in qaxserverbase.cpp
       
   170 
       
   171 /*!
       
   172     Reimplement this function to return the class identifier for each
       
   173     \a key returned by the featureList() implementation, or an empty
       
   174     QUuid if this factory doesn't support the value of \a key.
       
   175 
       
   176     The default implementation interprets \a key as the class name,
       
   177     and returns the value of the Q_CLASSINFO() entry "ClassID".
       
   178 */
       
   179 QUuid QAxFactory::classID(const QString &key) const
       
   180 {
       
   181     const QMetaObject *mo = metaObject(key);
       
   182     if (!mo)
       
   183         return QUuid();
       
   184     QString id = QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("ClassID")).value());
       
   185 
       
   186     return QUuid(id);
       
   187 }
       
   188 
       
   189 /*!
       
   190     Reimplement this function to return the interface identifier for
       
   191     each \a key returned by the featureList() implementation, or an
       
   192     empty QUuid if this factory doesn't support the value of \a key.
       
   193 
       
   194     The default implementation interprets \a key as the class name,
       
   195     and returns the value of the Q_CLASSINFO() entry "InterfaceID".
       
   196 */
       
   197 QUuid QAxFactory::interfaceID(const QString &key) const
       
   198 {
       
   199     const QMetaObject *mo = metaObject(key);
       
   200     if (!mo)
       
   201         return QUuid();
       
   202     QString id = QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("InterfaceID")).value());
       
   203 
       
   204     return QUuid(id);
       
   205 }
       
   206 
       
   207 /*!
       
   208     Reimplement this function to return the identifier of the event
       
   209     interface for each \a key returned by the featureList()
       
   210     implementation, or an empty QUuid if this factory doesn't support
       
   211     the value of \a key.
       
   212 
       
   213     The default implementation interprets \a key as the class name,
       
   214     and returns the value of the Q_CLASSINFO() entry "EventsID".
       
   215 */
       
   216 QUuid QAxFactory::eventsID(const QString &key) const
       
   217 {
       
   218     const QMetaObject *mo = metaObject(key);
       
   219     if (!mo)
       
   220         return QUuid();
       
   221     QString id = QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("EventsID")).value());
       
   222 
       
   223     return QUuid(id);
       
   224 }
       
   225 
       
   226 /*!
       
   227     Registers additional values for the class \a key in the system
       
   228     registry using the \a settings object. The standard values have
       
   229     already been registered by the framework, but additional values,
       
   230     e.g. implemented categories, can be added in an implementation of
       
   231     this function.
       
   232 
       
   233     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 3
       
   234 
       
   235     If you reimplement this function you must also reimplement
       
   236     unregisterClass() to remove the additional registry values.
       
   237 
       
   238     \sa QSettings
       
   239 */
       
   240 void QAxFactory::registerClass(const QString &key, QSettings *settings) const
       
   241 {
       
   242     Q_UNUSED(key);
       
   243     Q_UNUSED(settings)
       
   244 }
       
   245 
       
   246 /*!
       
   247     Unregisters any additional values for the class \a key from the
       
   248     system registry using the \a settings object.
       
   249 
       
   250     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 4
       
   251 
       
   252     \sa registerClass(), QSettings
       
   253 */
       
   254 void QAxFactory::unregisterClass(const QString &key, QSettings *settings) const
       
   255 {
       
   256     Q_UNUSED(key);
       
   257     Q_UNUSED(settings)
       
   258 }
       
   259 
       
   260 /*!
       
   261     Reimplement this function to return true if \a licenseKey is a valid
       
   262     license for the class \a key, or if the current machine is licensed.
       
   263 
       
   264     The default implementation returns true if the class \a key is
       
   265     not licensed (ie. no \c Q_CLASSINFO() attribute "LicenseKey"), or
       
   266     if  \a licenseKey matches the value of the "LicenseKey"
       
   267     attribute, or if the machine is licensed through a .LIC file with
       
   268     the same filename as this COM server.
       
   269 */
       
   270 bool QAxFactory::validateLicenseKey(const QString &key, const QString &licenseKey) const
       
   271 {
       
   272     const QMetaObject *mo = metaObject(key);
       
   273     if (!mo)
       
   274         return true;
       
   275 
       
   276     QString classKey = QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("LicenseKey")).value());
       
   277     if (classKey.isEmpty())
       
   278         return true;
       
   279 
       
   280     if (licenseKey.isEmpty()) {
       
   281         QString licFile(QString::fromWCharArray(qAxModuleFilename));
       
   282         int lastDot = licFile.lastIndexOf(QLatin1Char('.'));
       
   283         licFile = licFile.left(lastDot) + QLatin1String(".lic");
       
   284         if (QFile::exists(licFile))
       
   285             return true;
       
   286         return false;
       
   287     }
       
   288     return licenseKey == classKey;
       
   289 }
       
   290 
       
   291 /*!
       
   292     Reimplement this function to return the name of the super class of
       
   293     \a key up to which methods and properties should be exposed by the
       
   294     ActiveX control.
       
   295 
       
   296     The default implementation interprets \a key as the class name,
       
   297     and returns the value of the \c Q_CLASSINFO() entry
       
   298     "ToSuperClass". If no such value is set the null-string is
       
   299     returned, and the functions  and properties of all the super
       
   300     classes including QWidget will be  exposed.
       
   301 
       
   302     To only expose the functions and properties of the class itself,
       
   303     reimplement this function to return \a key.
       
   304 */
       
   305 QString QAxFactory::exposeToSuperClass(const QString &key) const
       
   306 {
       
   307     const QMetaObject *mo = metaObject(key);
       
   308     if (!mo)
       
   309         return QString();
       
   310     return QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("ToSuperClass")).value());
       
   311 }
       
   312 
       
   313 /*!
       
   314     Reimplement this function to return true if the ActiveX control \a key
       
   315     should be a top level window, e.g. a dialog. The default implementation
       
   316     returns false.
       
   317 */
       
   318 bool QAxFactory::stayTopLevel(const QString &key) const
       
   319 {
       
   320     return false;
       
   321 }
       
   322 
       
   323 /*!
       
   324     Reimplement this function to return true if the ActiveX control
       
   325     \a key should support the standard ActiveX events
       
   326     \list
       
   327     \i Click
       
   328     \i DblClick
       
   329     \i KeyDown
       
   330     \i KeyPress
       
   331     \i KeyUp
       
   332     \i MouseDown
       
   333     \i MouseUp
       
   334     \i MouseMove
       
   335     \endlist
       
   336 
       
   337     The default implementation interprets \a key as the class name,
       
   338     and returns true if the value of the \c Q_CLASSINFO() entry
       
   339     "StockEvents" is "yes". Otherwise this function returns false.
       
   340 */
       
   341 bool QAxFactory::hasStockEvents(const QString &key) const
       
   342 {
       
   343     const QMetaObject *mo = metaObject(key);
       
   344     if (!mo)
       
   345         return false;
       
   346     return QString::fromLatin1(mo->classInfo(mo->indexOfClassInfo("StockEvents")).value()) == QLatin1String("yes");
       
   347 }
       
   348 
       
   349 
       
   350 extern bool qAxIsServer;
       
   351 
       
   352 /*!
       
   353     Returns true if the application has been started (by COM) as an ActiveX
       
   354     server, otherwise returns false.
       
   355 
       
   356     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 5
       
   357 */
       
   358 
       
   359 bool QAxFactory::isServer()
       
   360 {
       
   361     return qAxIsServer;
       
   362 }
       
   363 
       
   364 extern wchar_t qAxModuleFilename[MAX_PATH];
       
   365 
       
   366 /*!
       
   367     Returns the directory that contains the server binary.
       
   368 
       
   369     For out-of-process servers this is the same as
       
   370     QApplication::applicationDirPath(). For in-process servers
       
   371     that function returns the directory that contains the hosting
       
   372     application.
       
   373 */
       
   374 QString QAxFactory::serverDirPath()
       
   375 {
       
   376     return QFileInfo(QString::fromWCharArray(qAxModuleFilename)).absolutePath();
       
   377 }
       
   378 
       
   379 /*!
       
   380     Returns the file path of the server binary.
       
   381 
       
   382     For out-of-process servers this is the same as
       
   383     QApplication::applicationFilePath(). For in-process servers
       
   384     that function returns the file path of the hosting application.
       
   385 */
       
   386 QString QAxFactory::serverFilePath()
       
   387 {
       
   388     return QString::fromWCharArray(qAxModuleFilename);
       
   389 }
       
   390 
       
   391 /*!
       
   392     Reimplement this function to return true if the server is
       
   393     running as a persistent service (e.g. an NT service) and should
       
   394     not terminate even when all objects provided have been released.
       
   395 
       
   396     The default implementation returns false.
       
   397 */
       
   398 bool QAxFactory::isService() const
       
   399 {
       
   400     return false;
       
   401 }
       
   402 
       
   403 /*!
       
   404     \enum QAxFactory::ServerType
       
   405 
       
   406     This enum specifies the different types of servers that can be
       
   407     started with startServer.
       
   408 
       
   409     \value SingleInstance The server process can create only one instance of each
       
   410     exported class. COM starts a new process for each request. This is typically
       
   411     used in servers that export only one creatable class.
       
   412     \value MultipleInstances The server can create multiple instances of
       
   413     each exported class. This is the default. All instances will live in the same
       
   414     thread, and will share static resources.
       
   415 */
       
   416 
       
   417 /*!
       
   418     \fn bool QAxFactory::startServer(ServerType type);
       
   419 
       
   420     Starts the COM server with \a type and returns true if successful,
       
   421     otherwise returns false.
       
   422 
       
   423     Calling this function if the server is already running (or for an
       
   424     in-process server) does nothing and returns true.
       
   425 
       
   426     The server is started automatically with \a type set to \c MultipleInstances
       
   427     if the server executable has been started with the \c -activex
       
   428     command line parameter. To switch to SingleInstance, call 
       
   429     
       
   430     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 6
       
   431 
       
   432     in your own main() entry point function.
       
   433 */
       
   434 
       
   435 /*!
       
   436     \fn bool QAxFactory::stopServer();
       
   437 
       
   438     Stops the COM server and returns true if successful, otherwise
       
   439     returns false.
       
   440 
       
   441     Calling this function if the server is not running (or for an
       
   442     in-process server) does nothing and returns true.
       
   443 
       
   444     Stopping the server will not invalidate existing objects, but no
       
   445     new objects can be created from the existing server process. Usually
       
   446     COM will start a new server process if additional objects are requested.
       
   447 
       
   448     The server is stopped automatically when the main() function returns.
       
   449 */
       
   450 
       
   451 class ActiveObject : public QObject
       
   452 {
       
   453 public:
       
   454     ActiveObject(QObject *parent, QAxFactory *factory);
       
   455     ~ActiveObject();
       
   456 
       
   457     IDispatch *wrapper;
       
   458     DWORD cookie;
       
   459 };
       
   460 
       
   461 ActiveObject::ActiveObject(QObject *parent, QAxFactory *factory)
       
   462 : QObject(parent), wrapper(0), cookie(0)
       
   463 {
       
   464     QLatin1String key(parent->metaObject()->className());
       
   465 
       
   466     factory->createObjectWrapper(parent, &wrapper);
       
   467     if (wrapper)
       
   468         RegisterActiveObject(wrapper, QUuid(factory->classID(key)), ACTIVEOBJECT_STRONG, &cookie);
       
   469 }
       
   470 
       
   471 ActiveObject::~ActiveObject()
       
   472 {
       
   473     if (cookie)
       
   474         RevokeActiveObject(cookie, 0);
       
   475     if (wrapper)
       
   476         wrapper->Release();
       
   477 }
       
   478 
       
   479 /*!
       
   480     Registers the QObject \a object with COM as a running object, and returns true if
       
   481     the registration succeeded, otherwise returns false. The object is unregistered
       
   482     automatically when it is destroyed.
       
   483 
       
   484     This function should only be called if the application has been started by the user
       
   485     (i.e. not by COM to respond to a request), and only for one object, usually the
       
   486     toplevel object of the application's object hierarchy.
       
   487 
       
   488     This function does nothing and returns false if the object's class info for
       
   489     "RegisterObject" is not set to "yes", or if the server is an in-process server.
       
   490 */
       
   491 bool QAxFactory::registerActiveObject(QObject *object)
       
   492 {
       
   493     if (qstricmp(object->metaObject()->classInfo(object->metaObject()->indexOfClassInfo("RegisterObject")).value(), "yes"))
       
   494         return false;
       
   495 
       
   496     if (!QString::fromWCharArray(qAxModuleFilename).toLower().endsWith(QLatin1String(".exe")))
       
   497 	return false;
       
   498 
       
   499     ActiveObject *active = new ActiveObject(object, qAxFactory());
       
   500     if (!active->wrapper || !active->cookie) {
       
   501         delete active;
       
   502         return false;
       
   503     }
       
   504     return true;
       
   505 }
       
   506 
       
   507 /*!
       
   508     \macro QAXFACTORY_DEFAULT(Class, ClassID, InterfaceID, EventID, LibID, AppID)
       
   509     \relates QAxFactory
       
   510 
       
   511     This macro can be used to export a single QObject subclass \a Class a this
       
   512     COM server through an implicitly declared QAxFactory implementation.
       
   513 
       
   514     This macro exports the class \a Class as a COM coclass with the CLSID \a ClassID.
       
   515     The properties and slots will be declared through a COM interface with the IID
       
   516     \a InterfaceID, and signals will be declared through a COM event interface with
       
   517     the IID \a EventID. All declarations will be in a type library with the id \a LibID,
       
   518     and if the server is an executable server then it will have the application id
       
   519     \a AppID.
       
   520 
       
   521     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 7
       
   522 
       
   523     \sa QAXFACTORY_EXPORT(), QAXFACTORY_BEGIN()
       
   524 */
       
   525 
       
   526 /*!
       
   527     \macro QAXFACTORY_EXPORT(Class, LibID, AppID)
       
   528     \relates QAxFactory
       
   529 
       
   530     This macro can be used to export a QAxFactory implementation \a Class from
       
   531     a COM server. All declarations will be in a type library with the id \a LibID,
       
   532     and if the server is an executable server then it will have the application id
       
   533     \a AppID.
       
   534 
       
   535     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 8
       
   536 
       
   537     \sa QAXFACTORY_BEGIN()
       
   538 */
       
   539 
       
   540 /*!
       
   541     \macro QAXFACTORY_BEGIN(IDTypeLib, IDApp)
       
   542     \relates QAxFactory
       
   543 
       
   544     This macro can be used to export multiple QObject classes through an
       
   545     implicitly declared QAxFactory implementation. All QObject classes have to
       
   546     declare the ClassID, InterfaceID and EventsID (if applicable) through the
       
   547     Q_CLASSINFO() macro. All declarations will be in a type library with the id
       
   548     \a IDTypeLib, and if the server is an executable server then it will have the
       
   549     application id \a IDApp.
       
   550 
       
   551     This macro needs to be used together with the QAXCLASS(), QAXTYPE()
       
   552     and QAXFACTORY_END() macros.
       
   553 
       
   554     \snippet doc/src/snippets/code/src_activeqt_control_qaxfactory.cpp 9
       
   555 */
       
   556 
       
   557 /*!
       
   558     \macro QAXCLASS(Class)
       
   559     \relates QAxFactory
       
   560 
       
   561     This macro adds a creatable COM class \a Class to the QAxFactory declared
       
   562     with the QAXFACTORY_BEGIN() macro.
       
   563 
       
   564     \sa QAXFACTORY_BEGIN(), QAXTYPE(), QAXFACTORY_END(), Q_CLASSINFO()
       
   565 */
       
   566 
       
   567 /*!
       
   568     \macro QAXTYPE(Class)
       
   569     \relates QAxFactory
       
   570 
       
   571     This macro adds a non-creatable COM class \a Class to the QAxFactory
       
   572     declared with the QAXFACTORY_BEGIN(). The class \a Class can be used
       
   573     in APIs of other COM classes exported through QAXTYPE() or QAXCLASS().
       
   574 
       
   575     Instances of type \a Class can only be retrieved using APIs of already
       
   576     instantiated objects.
       
   577 
       
   578     \sa QAXFACTORY_BEGIN(), QAXCLASS(), QAXFACTORY_END(), Q_CLASSINFO()
       
   579 */
       
   580 
       
   581 /*!
       
   582     \macro QAXFACTORY_END()
       
   583     \relates QAxFactory
       
   584 
       
   585     Completes the QAxFactory declaration started with the QAXFACTORY_BEGIN()
       
   586     macro.
       
   587 
       
   588     \sa QAXFACTORY_BEGIN(), QAXCLASS(), QAXTYPE()
       
   589 */
       
   590 
       
   591 QT_END_NAMESPACE
       
   592 #endif // QT_NO_WIN_ACTIVEQT