| 1 | /****************************************************************************
|
|---|
| 2 | **
|
|---|
| 3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|---|
| 4 | ** All rights reserved.
|
|---|
| 5 | ** Contact: Nokia Corporation ([email protected])
|
|---|
| 6 | **
|
|---|
| 7 | ** This file is part of the 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
|
|---|