diff options
-rw-r--r-- | .gitignore | 160 | ||||
-rw-r--r-- | .qmake.conf | 2 | ||||
-rw-r--r-- | src/activeqt/container/qaxselect.cpp | 4 | ||||
-rw-r--r-- | src/activeqt/container/qaxselect.ui | 8 | ||||
-rw-r--r-- | src/activeqt/control/control.pro | 2 | ||||
-rw-r--r-- | src/activeqt/control/qaxfactory.h | 4 | ||||
-rw-r--r-- | src/activeqt/control/qaxserver.cpp | 2 | ||||
-rw-r--r-- | src/activeqt/control/qaxserverbase.cpp | 155 | ||||
-rw-r--r-- | src/activeqt/control/qaxservermain.cpp | 26 | ||||
-rw-r--r-- | src/activeqt/doc/activeqt.qdocconf | 2 | ||||
-rw-r--r-- | src/activeqt/doc/src/activeqt-index.qdoc | 2 | ||||
-rw-r--r-- | src/activeqt/doc/src/qtaxserver.qdoc | 12 | ||||
-rw-r--r-- | src/tools/idc/main.cpp | 150 | ||||
-rw-r--r-- | tools/dumpcpp/main.cpp | 11 | ||||
-rw-r--r-- | tools/testcon/main.cpp | 41 | ||||
-rw-r--r-- | tools/testcon/mainwindow.cpp | 205 | ||||
-rw-r--r-- | tools/testcon/mainwindow.h | 26 | ||||
-rw-r--r-- | tools/testcon/mainwindow.ui | 8 | ||||
-rw-r--r-- | tools/testcon/scripts/hierarchyax.vbs | 55 |
19 files changed, 471 insertions, 404 deletions
@@ -5,19 +5,6 @@ examples/*/*/* !examples/*/*/*[.]* !examples/*/*/README examples/*/*/*[.]app -!examples/declarative/* -!examples/tutorials/* -!examples/tutorials/*/* -!examples/ja_JP/*/* -demos/*/* -!demos/spectrum/* -demos/spectrum/bin -!demos/*/*[.]* -demos/*/*[.]app -!demos/declarative/* -config.tests/*/*/* -!config.tests/*/*/*[.]* -config.tests/*/*/*[.]app callgrind.out.* pcviewer.cfg @@ -47,73 +34,14 @@ tags .DS_Store *.debug Makefile* -!qmake/Makefile.win32* -!qmake/Makefile.unix *.prl *.app *.pro.user *.qmlproject.user *.gcov -bin/Qt*.dll -bin/assistant* -bin/designer* -bin/dumpcpp* -bin/idc* -bin/linguist* -bin/lrelease* -bin/lupdate* -bin/lconvert* -bin/moc* -bin/makeqpf* -bin/pixeltool* -bin/qmake* -bin/qdoc3* -bin/qt3to4* -bin/qttracereplay* -bin/rcc* -bin/uic* -bin/patternist* -bin/phonon* -bin/qcollectiongenerator* -bin/qdbus* -bin/qhelpconverter* -bin/qhelpgenerator* -bin/qtconfig* -bin/xmlpatterns* -bin/cetest* -bin/collectiongenerator -bin/helpconverter -bin/helpgenerator -bin/kmap2qmap* -bin/qlalr* -bin/qmlconv* -bin/qmldebugger* -bin/qml* -bin/qttracereplay* -configure.cache -config.status -mkspecs/default -mkspecs/qconfig.pri moc_*.cpp -qmake/qmake.exe -qmake/Makefile.bak -src/corelib/global/qconfig.cpp -src/corelib/global/qconfig.h -src/corelib/global/qconfig.h.qmake ui_*.h -tests/auto/qprocess/test*/*.exe -tests/auto/qtcpsocket/stressTest/*.exe -tests/auto/qprocess/fileWriterProcess/*.exe -tests/auto/qmake/testdata/quotedfilenames/*.exe -tests/auto/compilerwarnings/*.exe -tests/auto/qmake/testdata/quotedfilenames/test.cpp -tests/auto/qprocess/fileWriterProcess.txt -.com.apple.timemachine.supported -tests/auto/qlibrary/libmylib.so* -tests/auto/qresourceengine/runtime_resource.rcc tools/activeqt/testcon/testcon.tlb -translations/*.qm -translations/*_untranslated.ts qrc_*.cpp # Test generated files @@ -148,52 +76,15 @@ tst_*~ *.Debug *.Release -# WebKit temp files -src/3rdparty/webkit/WebCore/mocinclude.tmp -src/3rdparty/webkit/includes.txt -src/3rdparty/webkit/includes2.txt - -# Symlinks generated by configure -tools/qvfb/qvfbhdr.h -tools/qvfb/qlock_p.h -tools/qvfb/qlock.cpp -tools/qvfb/qwssignalhandler.cpp -tools/qvfb/qwssignalhandler_p.h .DS_Store .pch .rcc *.app -config.status -config.tests/unix/cups/cups -config.tests/unix/getaddrinfo/getaddrinfo -config.tests/unix/getifaddrs/getifaddrs -config.tests/unix/iconv/iconv -config.tests/unix/ipv6/ipv6 -config.tests/unix/ipv6ifname/ipv6ifname -config.tests/unix/largefile/largefile -config.tests/unix/nis/nis -config.tests/unix/odbc/odbc -config.tests/unix/openssl/openssl -config.tests/unix/stl/stl -config.tests/unix/zlib/zlib -config.tests/unix/3dnow/3dnow -config.tests/unix/mmx/mmx -config.tests/unix/sse/sse -config.tests/unix/sse2/sse2 - - # Directories to ignore # --------------------- debug -examples/tools/plugandpaint/plugins -include/* -include/*/* -lib/* -!lib/fonts -!lib/README -plugins/*/* release tmp doc-build @@ -204,58 +95,7 @@ doc-build .pch .metadata -# Symbian build system generated files -# --------------------- - -ABLD.BAT -bld.inf* -*.mmp -*.mk -*.rss -*.loc -!s60main.rss -*.pkg -plugin_commonu.def -*.qtplugin -*.sis -*.sisx -*.lst -*.exe -*.mif -*.rsc -*.sym -*.lib - -# runonphone crash dumps -d_exc_*.txt -d_exc_*.stk - -# Generated by abldfast.bat from devtools. -.abldsteps.* - -# Carbide project files -# --------------------- -.project -.cproject -.make.cache -*.d - -qtc-debugging-helper -src/corelib/lib -src/network/lib -src/xml/lib/ - .pc/ -# INTEGRITY generated files -*.gpj -*.int -*.ael -*.dla -*.dnm -*.dep -*.map -work - # Generated static plugin import sources *_plugin_import.cpp diff --git a/.qmake.conf b/.qmake.conf index fd7c2fa..a9b6a32 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,4 +1,4 @@ load(qt_build_config) CONFIG += qt_example_installs -MODULE_VERSION = 5.5.1 +MODULE_VERSION = 5.6.0 diff --git a/src/activeqt/container/qaxselect.cpp b/src/activeqt/container/qaxselect.cpp index ff56dc3..b091b1c 100644 --- a/src/activeqt/container/qaxselect.cpp +++ b/src/activeqt/container/qaxselect.cpp @@ -47,6 +47,7 @@ #include <QtCore/QSysInfo> #include <QtCore/QTextStream> #include <QtCore/QRegExp> +#include <QtWidgets/QDesktopWidget> #include <QtWidgets/QPushButton> #include <qt_windows.h> @@ -289,6 +290,9 @@ QAxSelect::QAxSelect(QWidget *parent, Qt::WindowFlags flags) d->selectUi.setupUi(this); d->setOkButtonEnabled(false); + const QRect availableGeometry = QApplication::desktop()->availableGeometry(this); + resize(availableGeometry.width() / 4, availableGeometry.height() * 2 / 3); + #ifndef QT_NO_CURSOR QApplication::setOverrideCursor(Qt::WaitCursor); #endif diff --git a/src/activeqt/container/qaxselect.ui b/src/activeqt/container/qaxselect.ui index 25b8490..0ec11c1 100644 --- a/src/activeqt/container/qaxselect.ui +++ b/src/activeqt/container/qaxselect.ui @@ -41,14 +41,6 @@ *********************************************************************</comment> <class>QAxSelect</class> <widget class="QDialog" name="QAxSelect"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>439</width> - <height>326</height> - </rect> - </property> <property name="windowTitle"> <string>Select ActiveX Control</string> </property> diff --git a/src/activeqt/control/control.pro b/src/activeqt/control/control.pro index c579ce8..b87c30e 100644 --- a/src/activeqt/control/control.pro +++ b/src/activeqt/control/control.pro @@ -5,6 +5,8 @@ CONFIG += static DEFINES += QAX_SERVER +mingw: DEFINES += QT_NEEDS_QMAIN + HEADERS = qaxaggregated.h \ qaxbindable.h \ qaxfactory.h \ diff --git a/src/activeqt/control/qaxfactory.h b/src/activeqt/control/qaxfactory.h index ac7a9e9..6d86a4e 100644 --- a/src/activeqt/control/qaxfactory.h +++ b/src/activeqt/control/qaxfactory.h @@ -220,7 +220,7 @@ public: factory = new QAxClass<Class>(typeLibID().toString(), appID().toString()); \ qRegisterMetaType<Class*>(#Class"*"); \ keys = factory->featureList(); \ - foreach (const QString &key, keys) { \ + Q_FOREACH (const QString &key, keys) { \ factoryKeys += key; \ factories.insert(key, factory); \ creatable.insert(key, true); \ @@ -230,7 +230,7 @@ public: factory = new QAxClass<Class>(typeLibID().toString(), appID().toString()); \ qRegisterMetaType<Class*>(#Class"*"); \ keys = factory->featureList(); \ - foreach (const QString &key, keys) { \ + Q_FOREACH (const QString &key, keys) { \ factoryKeys += key; \ factories.insert(key, factory); \ creatable.insert(key, false); \ diff --git a/src/activeqt/control/qaxserver.cpp b/src/activeqt/control/qaxserver.cpp index 2de749f..1703765 100644 --- a/src/activeqt/control/qaxserver.cpp +++ b/src/activeqt/control/qaxserver.cpp @@ -330,7 +330,7 @@ HRESULT UpdateRegistry(BOOL bRegister) QString extension; while (mime.contains(QLatin1Char(':'))) { extension = mime.mid(mime.lastIndexOf(QLatin1Char(':')) + 1); - mime.chop(extension.length() - 1); + mime.chop(extension.length() + 1); // Prepend '.' before extension, if required. extension = extension.trimmed(); if (!extension.startsWith(dot)) diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index b788e07..5efdae9 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -342,6 +342,17 @@ public: int qt_metacall(QMetaObject::Call, int index, void **argv); bool eventFilter(QObject *o, QEvent *e); + + RECT rcPosRect() const + { + RECT result = {0, 0, 1, 1}; + if (qt.widget) { + result.right = qt.widget->width() + 1; + result.bottom = qt.widget->height() + 1; + } + return result; + } + private: void update(); void resize(const QSize &newSize); @@ -411,6 +422,15 @@ private: QSize m_currentExtent; }; +static inline QAxServerBase *axServerBaseFromWindow(HWND hWnd) +{ +#ifdef GWLP_USERDATA + return reinterpret_cast<QAxServerBase *>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); +#else + return reinterpret_cast<QAxServerBase *>(GetWindowLong(hWnd, GWL_USERDATA)); +#endif +} + class QAxServerAggregate : public IUnknown { public: @@ -800,12 +820,7 @@ bool QAxWinEventFilter::nativeEventFilter(const QByteArray &, void *message, lon HWND baseHwnd = hwndForWidget(aqt); QAxServerBase *axbase = 0; while (!axbase && baseHwnd) { -#ifdef GWLP_USERDATA - axbase = (QAxServerBase*)GetWindowLongPtr(baseHwnd, GWLP_USERDATA); -#else - axbase = (QAxServerBase*)GetWindowLong(baseHwnd, GWL_USERDATA); -#endif - + axbase = axServerBaseFromWindow(baseHwnd); baseHwnd = ::GetParent(baseHwnd); } if (!axbase) @@ -1377,73 +1392,68 @@ LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } - QAxServerBase *that = 0; - -#ifdef GWLP_USERDATA - that = (QAxServerBase*)GetWindowLongPtr(hWnd, GWLP_USERDATA); -#else - that = (QAxServerBase*)GetWindowLong(hWnd, GWL_USERDATA); -#endif - - if (that) { - int width = that->qt.widget ? that->qt.widget->width() : 0; - int height = that->qt.widget ? that->qt.widget->height() : 0; - RECT rcPos = {0, 0, width + 1, height + 1}; - - switch (uMsg) { - case WM_NCDESTROY: + switch (uMsg) { + case WM_NCDESTROY: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) that->m_hWnd = 0; - break; + break; - case WM_QUERYENDSESSION: - case WM_DESTROY: - if (that->qt.widget) { + case WM_QUERYENDSESSION: + case WM_DESTROY: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) { + if (that->qt.widget) that->qt.widget->hide(); - } - break; + } + break; - case WM_SHOWWINDOW: - if (wParam) { + case WM_SHOWWINDOW: + if (wParam) { + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) { that->internalCreate(); if (!that->stayTopLevel) { - // Set this property on window to pass the native handle to platform plugin, - // so that it can create the window with proper flags instead of thinking - // it is toplevel. - that->qt.widget->setProperty("_q_embedded_native_parent_handle", WId(that->m_hWnd)); - - if (QWindow *widgetWindow = that->qt.widget->windowHandle()) { - // If embedded widget is native, such as QGLWidget, it may have already created - // a window before now, probably as an undesired toplevel. In that case set the - // proper parent window and set the window frameless to position it correctly. - if (that->qt.widget->testAttribute(Qt::WA_WState_Created) - && !that->qt.widget->isVisible()) { - HWND h = static_cast<HWND>(QGuiApplication::platformNativeInterface()-> - nativeResourceForWindow("handle", widgetWindow)); - if (h) - ::SetParent(h, that->m_hWnd); - Qt::WindowFlags flags = widgetWindow->flags(); - widgetWindow->setFlags(flags | Qt::FramelessWindowHint); + // Set this property on window to pass the native handle to platform plugin, + // so that it can create the window with proper flags instead of thinking + // it is toplevel. + that->qt.widget->setProperty("_q_embedded_native_parent_handle", WId(that->m_hWnd)); + + if (QWindow *widgetWindow = that->qt.widget->windowHandle()) { + // If embedded widget is native, such as QGLWidget, it may have already created + // a window before now, probably as an undesired toplevel. In that case set the + // proper parent window and set the window frameless to position it correctly. + if (that->qt.widget->testAttribute(Qt::WA_WState_Created) + && !that->qt.widget->isVisible()) { + HWND h = static_cast<HWND>(QGuiApplication::platformNativeInterface()-> + nativeResourceForWindow("handle", widgetWindow)); + if (h) + ::SetParent(h, that->m_hWnd); + Qt::WindowFlags flags = widgetWindow->flags(); + widgetWindow->setFlags(flags | Qt::FramelessWindowHint); + } } - } - that->qt.widget->raise(); - that->qt.widget->move(0, 0); + that->qt.widget->raise(); + that->qt.widget->move(0, 0); } that->qt.widget->show(); } else if (that->qt.widget) { that->qt.widget->hide(); } - break; + } + break; - case WM_ERASEBKGND: + case WM_ERASEBKGND: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) that->updateMask(); - break; + break; - case WM_SIZE: + case WM_SIZE: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) that->resize(QSize(LOWORD(lParam), HIWORD(lParam))); - break; + break; - case WM_SETFOCUS: + case WM_SETFOCUS: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) { if (that->isInPlaceActive && that->m_spClientSite && !that->inDesignMode && that->canTakeFocus) { + RECT rcPos = that->rcPosRect(); that->DoVerb(OLEIVERB_UIACTIVATE, NULL, that->m_spClientSite, 0, that->m_hWnd, &rcPos); if (that->isUIActive) { IOleControlSite *spSite = 0; @@ -1468,9 +1478,11 @@ LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM } } } - break; + } + break; - case WM_KILLFOCUS: + case WM_KILLFOCUS: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) { if (that->isInPlaceActive && that->isUIActive && that->m_spClientSite) { IOleControlSite *spSite = 0; that->m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&spSite); @@ -1480,13 +1492,18 @@ LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM spSite->Release(); } } - break; + } + break; - case WM_MOUSEACTIVATE: + case WM_MOUSEACTIVATE: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) { + RECT rcPos = that->rcPosRect(); that->DoVerb(OLEIVERB_UIACTIVATE, NULL, that->m_spClientSite, 0, that->m_hWnd, &rcPos); - break; + } + break; - case WM_INITMENUPOPUP: + case WM_INITMENUPOPUP: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) { if (that->qt.widget) { that->currentPopup = that->menuMap[(HMENU)wParam]; if (!that->currentPopup) @@ -1500,10 +1517,12 @@ LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM that->createPopup(that->currentPopup, (HMENU)wParam); return 0; } - break; + } + break; - case WM_MENUSELECT: - case WM_COMMAND: + case WM_MENUSELECT: + case WM_COMMAND: + if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) { if (that->qt.widget) { QMenuBar *menuBar = that->menuBar; if (!menuBar) @@ -1541,11 +1560,11 @@ LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM return 0; } } - break; - - default: - break; } + break; + + default: + break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); diff --git a/src/activeqt/control/qaxservermain.cpp b/src/activeqt/control/qaxservermain.cpp index ae3f5b5..96cd503 100644 --- a/src/activeqt/control/qaxservermain.cpp +++ b/src/activeqt/control/qaxservermain.cpp @@ -243,15 +243,23 @@ EXTERN_C int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR, if (run) { if (SUCCEEDED(CoInitialize(0))) { - int argc; - QVector<char*> argv(8); - qWinMain(hInstance, hPrevInstance, unprocessed.data(), nShowCmd, argc, argv); - qAxInit(); - if (runServer) - QAxFactory::startServer(); - nRet = ::main(argc, argv.data()); - QAxFactory::stopServer(); - qAxCleanup(); + { + struct Arg { + int c; + QVector<char*> v; + + Arg() : v(8) {} + ~Arg() { Q_FOREACH (char *arg, v) free(arg); } + } arg; + + qWinMain(hInstance, hPrevInstance, unprocessed.data(), nShowCmd, arg.c, arg.v); + qAxInit(); + if (runServer) + QAxFactory::startServer(); + nRet = ::main(arg.c, arg.v.data()); + QAxFactory::stopServer(); + qAxCleanup(); + } CoUninitialize(); } else { qErrnoWarning("CoInitialize() failed."); diff --git a/src/activeqt/doc/activeqt.qdocconf b/src/activeqt/doc/activeqt.qdocconf index f5f2594..df3175b 100644 --- a/src/activeqt/doc/activeqt.qdocconf +++ b/src/activeqt/doc/activeqt.qdocconf @@ -4,7 +4,7 @@ project = ActiveQt description = ActiveQt version = $QT_VERSION -examplesinstallpath = +examplesinstallpath = qtactiveqt qhp.projects = ActiveQt diff --git a/src/activeqt/doc/src/activeqt-index.qdoc b/src/activeqt/doc/src/activeqt-index.qdoc index 7997060..af996ce 100644 --- a/src/activeqt/doc/src/activeqt-index.qdoc +++ b/src/activeqt/doc/src/activeqt-index.qdoc @@ -39,7 +39,7 @@ \page activeqt-index.html \ingroup qt-activex \keyword ActiveQt - \target ActiveQt Framework + \keyword ActiveQt Framework \title Active Qt \brief Provides ActiveX and COM integration on Windows diff --git a/src/activeqt/doc/src/qtaxserver.qdoc b/src/activeqt/doc/src/qtaxserver.qdoc index 97ddcf3..4aca87c 100644 --- a/src/activeqt/doc/src/qtaxserver.qdoc +++ b/src/activeqt/doc/src/qtaxserver.qdoc @@ -221,10 +221,10 @@ 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. + environment settings specified in the "Directories" option). + Make sure that all DLLs and plugins required by your server are located + in a directory that is listed in the path as printed in the error + message box (see also \l{The Windows Deployment Tool}). \section3 "Cannot open file ..." @@ -234,6 +234,10 @@ manager to kill the process (e.g. when a client doesn't release the controls properly). + \section3 The Control Cannot be Instantiated + + In this case, it may help to register the server as Administrator. + \section1 Implementing Controls To implement a COM object with Qt, create a subclass of QObject diff --git a/src/tools/idc/main.cpp b/src/tools/idc/main.cpp index 6f00477..1e2e311 100644 --- a/src/tools/idc/main.cpp +++ b/src/tools/idc/main.cpp @@ -170,21 +170,39 @@ static bool attachTypeLibrary(const QString &applicationName, int resource, cons return true; } +// Manually add defines that are missing from pre-VS2012 compilers +#ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR +# define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 +#endif +#ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS +# define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 +#endif + +static HMODULE loadLibraryQt(const QString &input) +{ + if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA) + return LoadLibrary((const wchar_t *)input.utf16()); // fallback for Windows XP and older + + // Load DLL with the folder containing the DLL temporarily added to the search path when loading dependencies + return LoadLibraryEx((const wchar_t *)input.utf16(), NULL, + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); +} + static bool registerServer(const QString &input) { bool ok = false; if (hasExeExtension(input)) { ok = runWithQtInEnvironment(quotePath(input) + QLatin1String(" -regserver")); } else { - HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16()); + HMODULE hdll = loadLibraryQt(input); if (!hdll) { - fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Couldn't load library file %s\n", qPrintable(input)); return false; } typedef HRESULT(__stdcall* RegServerProc)(); RegServerProc DllRegisterServer = (RegServerProc)GetProcAddress(hdll, "DllRegisterServer"); if (!DllRegisterServer) { - fprintf(stderr, "Library file %s doesn't appear to be a COM library\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Library file %s doesn't appear to be a COM library\n", qPrintable(input)); return false; } ok = DllRegisterServer() == S_OK; @@ -198,15 +216,15 @@ static bool unregisterServer(const QString &input) if (hasExeExtension(input)) { ok = runWithQtInEnvironment(quotePath(input) + QLatin1String(" -unregserver")); } else { - HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16()); + HMODULE hdll = loadLibraryQt(input); if (!hdll) { - fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Couldn't load library file %s\n", qPrintable(input)); return false; } typedef HRESULT(__stdcall* RegServerProc)(); RegServerProc DllUnregisterServer = (RegServerProc)GetProcAddress(hdll, "DllUnregisterServer"); if (!DllUnregisterServer) { - fprintf(stderr, "Library file %s doesn't appear to be a COM library\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Library file %s doesn't appear to be a COM library\n", qPrintable(input)); return false; } ok = DllUnregisterServer() == S_OK; @@ -222,15 +240,15 @@ static HRESULT dumpIdl(const QString &input, const QString &idlfile, const QStri if (runWithQtInEnvironment(quotePath(input) + QLatin1String(" -dumpidl ") + idlfile + QLatin1String(" -version ") + version)) res = S_OK; } else { - HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16()); + HMODULE hdll = loadLibraryQt(input); if (!hdll) { - fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Couldn't load library file %s\n", qPrintable(input)); return 3; } typedef HRESULT(__stdcall* DumpIDLProc)(const QString&, const QString&); DumpIDLProc DumpIDL = (DumpIDLProc)GetProcAddress(hdll, "DumpIDL"); if (!DumpIDL) { - fprintf(stderr, "Couldn't resolve 'DumpIDL' symbol in %s\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Couldn't resolve 'DumpIDL' symbol in %s\n", qPrintable(input)); return 3; } res = DumpIDL(idlfile, version); @@ -240,6 +258,26 @@ static HRESULT dumpIdl(const QString &input, const QString &idlfile, const QStri return res; } +const char usage[] = +"Usage: idc [options] [input_file]\n" +"Interface Description Compiler " QT_VERSION_STR "\n\n" +"Options:\n" +" -?, /h, -h, -help Displays this help.\n" +" /v, -v Displays version information.\n" +" /version, -version <version> Specify the interface version.\n" +" /idl, -idl <file> Specify the interface definition file.\n" +" /tlb, -tlb <file> Specify the type library file.\n" +" /regserver, -regserver Register server.\n" +" /unregserver, -unregserver Unregister server.\n\n" +"Examples:\n" +"idc -regserver l.dll Register the COM server l.dll\n" +"idc -unregserver l.dll Unregister the COM server l.dll\n" +"idc l.dll -idl l.idl -version 2.3 Writes the IDL of the server dll to the file idl.\n" +" The type library will have version 2.3\n" +"idc l.dll -tlb l.tlb Replaces the type library in l.dll with l.tlb\n"; + +enum Mode { RegisterServer, UnregisterServer, Other }; + int runIdc(int argc, char **argv) { QString error; @@ -247,6 +285,7 @@ int runIdc(int argc, char **argv) QString idlfile; QString input; QString version = QLatin1String("1.0"); + Mode mode = Other; int i = 1; while (i < argc) { @@ -258,8 +297,7 @@ int runIdc(int argc, char **argv) error = QLatin1String("Missing name for interface definition file!"); break; } - idlfile = QLatin1String(argv[i]); - idlfile = idlfile.trimmed(); + idlfile = QFile::decodeName(argv[i]).trimmed(); } else if (p == QLatin1String("/version") || p == QLatin1String("-version")) { ++i; if (i > argc) @@ -272,43 +310,56 @@ int runIdc(int argc, char **argv) error = QLatin1String("Missing name for type library file!"); break; } - tlbfile = QLatin1String(argv[i]); - tlbfile = tlbfile.trimmed(); + tlbfile = QFile::decodeName(argv[i]).trimmed(); } else if (p == QLatin1String("/v") || p == QLatin1String("-v")) { - fprintf(stdout, "Qt Interface Definition Compiler version 1.0\n"); + fprintf(stdout, "Qt Interface Definition Compiler version 1.0 using Qt %s\n", QT_VERSION_STR); return 0; - } else if (p == QLatin1String("/regserver") || p == QLatin1String("-regserver")) { - if (!registerServer(input)) { - fprintf(stderr, "Failed to register server!\n"); - return 1; - } - fprintf(stderr, "Server registered successfully!\n"); + } else if (p == QLatin1String("/h") || p == QLatin1String("-h") || p == QLatin1String("-?") || p == QLatin1String("/?")) { + fprintf(stdout, "%s\n", usage); return 0; + } else if (p == QLatin1String("/regserver") || p == QLatin1String("-regserver")) { + mode = RegisterServer; } else if (p == QLatin1String("/unregserver") || p == QLatin1String("-unregserver")) { - if (!unregisterServer(input)) { - fprintf(stderr, "Failed to unregister server!\n"); - return 1; - } - fprintf(stderr, "Server unregistered successfully!\n"); - return 0; + mode = UnregisterServer; } else if (p[0] == QLatin1Char('/') || p[0] == QLatin1Char('-')) { - error = QLatin1String("Unknown option \"") + p + QLatin1Char('\"'); + error = QLatin1String("Unknown option \"") + p + QLatin1Char('"'); break; } else { - input = QLatin1String(argv[i]); - input = input.trimmed(); + input = QFile::decodeName(argv[i]).trimmed(); + // LoadLibraryEx requires a fully qualified path when used together with LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR + input = QFileInfo(input).absoluteFilePath(); + input = QDir::toNativeSeparators(input); } i++; } if (!error.isEmpty()) { - fprintf(stderr, "%s", error.toLatin1().data()); - fprintf(stderr, "\n"); + fprintf(stderr, "%s\n", qPrintable(error)); return 5; } if (input.isEmpty()) { - fprintf(stderr, "No input file specified!\n"); + fprintf(stderr, "No input file specified!\n\n%s\n", usage); return 1; } + + switch (mode) { + case RegisterServer: + if (!registerServer(input)) { + fprintf(stderr, "Failed to register server!\n"); + return 1; + } + fprintf(stderr, "Server registered successfully!\n"); + return 0; + case UnregisterServer: + if (!unregisterServer(input)) { + fprintf(stderr, "Failed to unregister server!\n"); + return 1; + } + fprintf(stderr, "Server unregistered successfully!\n"); + return 0; + case Other: + break; + } + if (hasExeExtension(input) && tlbfile.isEmpty() && idlfile.isEmpty()) { fprintf(stderr, "No type output file specified!\n"); return 2; @@ -317,57 +368,52 @@ int runIdc(int argc, char **argv) fprintf(stderr, "No interface definition file and no type library file specified!\n"); return 3; } - input = QDir::toNativeSeparators(input); if (!tlbfile.isEmpty()) { tlbfile = QDir::toNativeSeparators(tlbfile); QFile file(tlbfile); if (!file.open(QIODevice::ReadOnly)) { - fprintf(stderr, "Couldn't open %s for read\n", (const char*)tlbfile.toLocal8Bit().data()); + fprintf(stderr, "Couldn't open %s for read: %s\n", qPrintable(tlbfile), qPrintable(file.errorString())); return 4; } - QByteArray data = file.readAll(); QString error; - bool ok = attachTypeLibrary(input, 1, data, &error); - fprintf(stderr, "%s", error.toLatin1().data()); - fprintf(stderr, "\n"); + const bool ok = attachTypeLibrary(input, 1, file.readAll(), &error); + fprintf(stderr, "%s\n", qPrintable(error)); return ok ? 0 : 4; } else if (!idlfile.isEmpty()) { - idlfile = QDir::toNativeSeparators(idlfile); - idlfile = quotePath(idlfile); - fprintf(stderr, "\n\n%s\n\n", (const char*)idlfile.toLocal8Bit().data()); - quotePath(input); - HRESULT res = dumpIdl(input, idlfile, version); + idlfile = quotePath(QDir::toNativeSeparators(idlfile)); + fprintf(stderr, "\n\n%s\n\n", qPrintable(idlfile)); + const HRESULT res = dumpIdl(input, idlfile, version); switch (res) { case S_OK: break; case E_FAIL: - fprintf(stderr, "IDL generation failed trying to run program %s!\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "IDL generation failed trying to run program %s!\n", qPrintable(input)); return res; case -1: - fprintf(stderr, "Couldn't open %s for writing!\n", (const char*)idlfile.toLocal8Bit().data()); + fprintf(stderr, "Couldn't open %s for writing!\n", qPrintable(idlfile)); return res; case 1: - fprintf(stderr, "Malformed appID value in %s!\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Malformed appID value in %s!\n", qPrintable(input)); return res; case 2: - fprintf(stderr, "Malformed typeLibID value in %s!\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Malformed typeLibID value in %s!\n", qPrintable(input)); return res; case 3: - fprintf(stderr, "Class has no metaobject information (error in %s)!\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Class has no metaobject information (error in %s)!\n", qPrintable(input)); return res; case 4: - fprintf(stderr, "Malformed classID value in %s!\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Malformed classID value in %s!\n", qPrintable(input)); return res; case 5: - fprintf(stderr, "Malformed interfaceID value in %s!\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Malformed interfaceID value in %s!\n", qPrintable(input)); return res; case 6: - fprintf(stderr, "Malformed eventsID value in %s!\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Malformed eventsID value in %s!\n", qPrintable(input)); return res; default: - fprintf(stderr, "Unknown error writing IDL from %s\n", (const char*)input.toLocal8Bit().data()); + fprintf(stderr, "Unknown error writing IDL from %s\n", qPrintable(input)); return 7; } } diff --git a/tools/dumpcpp/main.cpp b/tools/dumpcpp/main.cpp index 692ae67..c65d5cd 100644 --- a/tools/dumpcpp/main.cpp +++ b/tools/dumpcpp/main.cpp @@ -54,8 +54,7 @@ static ITypeInfo *currentTypeInfo = 0; enum ProgramMode { GenerateMode, - TypeLibID, - DoNothing + TypeLibID }; enum ObjectCategory @@ -1476,9 +1475,6 @@ static void parseOptions(Options *options) QCommandLineOption noImplementationOption(QStringLiteral("decl"), QStringLiteral("Only generate the .h file.")); parser.addOption(noImplementationOption); - QCommandLineOption doNothingOption(QStringLiteral("donothing"), - QStringLiteral("Do not generate any files.")); - parser.addOption(doNothingOption); QCommandLineOption compatOption(QStringLiteral("compat"), QStringLiteral("Treat all coclass parameters as IDispatch.")); parser.addOption(compatOption); @@ -1500,8 +1496,6 @@ static void parseOptions(Options *options) options->category |= NoDeclaration; if (parser.isSet(noImplementationOption)) options->category |= NoImplementation; - if (parser.isSet(doNothingOption)) - options->mode = DoNothing; options->dispatchEqualsIDispatch = parser.isSet(compatOption); if (parser.isSet(getFileOption)) { options->typeLib = parser.value(getFileOption); @@ -1545,9 +1539,6 @@ int main(int argc, char **argv) return 0; } - if (options.mode == DoNothing) - return 0; - if (typeLib.isEmpty()) { qWarning("dumpcpp: No object class or type library name provided.\n" " Use -h for help."); diff --git a/tools/testcon/main.cpp b/tools/testcon/main.cpp index dda1b3a..863a9e4 100644 --- a/tools/testcon/main.cpp +++ b/tools/testcon/main.cpp @@ -35,6 +35,10 @@ #include <QApplication> #include <QAxFactory> +#include <QCommandLineParser> +#include <QCommandLineOption> +#include <QDebug> +#include <QDesktopWidget> QAXFACTORY_DEFAULT(MainWindow, QLatin1String("{5f5ce700-48a8-47b1-9b06-3b7f79e41d7c}"), @@ -45,11 +49,48 @@ QAXFACTORY_DEFAULT(MainWindow, QT_USE_NAMESPACE +static void redirectDebugOutput(QtMsgType, const QMessageLogContext &, const QString &msg) +{ + if (MainWindow *mainWindow = MainWindow::instance()) + mainWindow->appendLogText(msg); +} + int main( int argc, char **argv ) { QApplication app( argc, argv ); + QCoreApplication::setApplicationName(QLatin1String("TestCon")); + QCoreApplication::setOrganizationName(QLatin1String("QtProject")); + QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); + QCommandLineParser parser; + parser.setApplicationDescription(QLatin1String("ActiveX Control Test Container")); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption scriptOption(QLatin1String("script"), + QLatin1String("A script to load."), + QLatin1String("script")); + parser.addOption(scriptOption); + QCommandLineOption noMessageHandlerOption(QLatin1String("no-messagehandler"), + QLatin1String("Suppress installation of the message handler.")); + parser.addOption(noMessageHandlerOption); + parser.addPositionalArgument(QLatin1String("clsid/file"), + QLatin1String("The clsid/file to show.")); + parser.process(app); + + if (!parser.isSet(noMessageHandlerOption)) + qInstallMessageHandler(redirectDebugOutput); MainWindow mw; + foreach (const QString &a, parser.positionalArguments()) { + if (a.startsWith(QLatin1Char('{')) && a.endsWith(QLatin1Char('}'))) + mw.addControlFromClsid(a); + else + mw.addControlFromFile(a); + } + if (parser.isSet(scriptOption)) + mw.loadScript(parser.value(scriptOption)); + + const QRect availableGeometry = QApplication::desktop()->availableGeometry(&mw); + mw.resize(availableGeometry.size() * 2 / 3); mw.show(); return app.exec();; diff --git a/tools/testcon/mainwindow.cpp b/tools/testcon/mainwindow.cpp index cc03f5a..98550ab 100644 --- a/tools/testcon/mainwindow.cpp +++ b/tools/testcon/mainwindow.cpp @@ -43,6 +43,8 @@ #include <QtWidgets/QFileDialog> #include <QtWidgets/QInputDialog> #include <QtWidgets/QMessageBox> +#include <QtGui/QCloseEvent> +#include <QtCore/QDebug> #include <QtCore/qt_windows.h> #include <ActiveQt/QAxScriptManager> #include <ActiveQt/QAxSelect> @@ -51,53 +53,60 @@ QT_BEGIN_NAMESPACE -QAxObject *ax_mainWindow = 0; +QT_END_NAMESPACE -static QTextEdit *debuglog = 0; +QT_USE_NAMESPACE -static void redirectDebugOutput(QtMsgType type, const QMessageLogContext &, const QString &msg) -{ - Q_UNUSED(type); - debuglog->append(msg); -} +struct ScriptLanguage { + const char *name; + const char *suffix; +}; -QT_END_NAMESPACE +static const ScriptLanguage scriptLanguages[] = { + {"PerlScript", ".pl"}, + {"Python", ".py"} +}; -QT_USE_NAMESPACE +MainWindow *MainWindow::m_instance = Q_NULLPTR; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) + , m_dlgInvoke(Q_NULLPTR) + , m_dlgProperties(Q_NULLPTR) + , m_dlgAmbient(Q_NULLPTR) + , m_scripts(Q_NULLPTR) { setupUi(this); + MainWindow::m_instance = this; // Logging handler needs the UI + setObjectName(QLatin1String("MainWindow")); - QAxScriptManager::registerEngine(QLatin1String("PerlScript"), QLatin1String(".pl")); - QAxScriptManager::registerEngine(QLatin1String("Python"), QLatin1String(".py")); + const int scriptCount = int(sizeof(scriptLanguages) / sizeof(scriptLanguages[0])); + for (int s = 0; s < scriptCount; ++s) { + const QString name = QLatin1String(scriptLanguages[s].name); + const QString suffix = QLatin1String(scriptLanguages[s].suffix); + if (!QAxScriptManager::registerEngine(name, suffix)) + qWarning().noquote().nospace() << "Failed to register \"" << name + << "\" (*" << suffix << ") with QAxScriptManager."; + } - dlgInvoke = 0; - dlgProperties = 0; - dlgAmbient = 0; - scripts = 0; - debuglog = logDebug; - oldDebugHandler = qInstallMessageHandler(redirectDebugOutput); QHBoxLayout *layout = new QHBoxLayout(Workbase); - mdiArea = new QMdiArea(Workbase); - layout->addWidget(mdiArea); + m_mdiArea = new QMdiArea(Workbase); + layout->addWidget(m_mdiArea); layout->setMargin(0); - connect(mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::updateGUI); + connect(m_mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::updateGUI); connect(actionFileExit, &QAction::triggered, QCoreApplication::quit); } MainWindow::~MainWindow() { - qInstallMessageHandler(oldDebugHandler); - debuglog = 0; + MainWindow::m_instance = Q_NULLPTR; } QAxWidget *MainWindow::activeAxWidget() const { - if (const QMdiSubWindow *activeSubWindow = mdiArea->currentSubWindow()) + if (const QMdiSubWindow *activeSubWindow = m_mdiArea->currentSubWindow()) return qobject_cast<QAxWidget*>(activeSubWindow->widget()); return 0; } @@ -105,47 +114,80 @@ QAxWidget *MainWindow::activeAxWidget() const QList<QAxWidget *> MainWindow::axWidgets() const { QList<QAxWidget *> result; - foreach (const QMdiSubWindow *subWindow, mdiArea->subWindowList()) + foreach (const QMdiSubWindow *subWindow, m_mdiArea->subWindowList()) if (QAxWidget *axWidget = qobject_cast<QAxWidget *>(subWindow->widget())) result.push_back(axWidget); return result; } -void MainWindow::on_actionFileNew_triggered() +bool MainWindow::addControlFromClsid(const QString &clsid) { - QAxSelect select(this); - if (select.exec()) { - QAxWidget *container = new QAxWidget; - container->setControl(select.clsid()); + QAxWidget *container = new QAxWidget; + const bool result = container->setControl(clsid); + if (result) { container->setObjectName(container->windowTitle()); - mdiArea->addSubWindow(container); + m_mdiArea->addSubWindow(container); container->show(); + updateGUI(); + } else { + delete container; + QMessageBox::information(this, + tr("Error Loading Control"), + tr("The control \"%1\" could not be loaded.").arg(clsid)); } - updateGUI(); + return result; +} + +void MainWindow::closeEvent(QCloseEvent *e) +{ + // Controls using the same version of Qt may set this to false, causing hangs. + QGuiApplication::setQuitOnLastWindowClosed(true); + m_mdiArea->closeAllSubWindows(); + e->accept(); +} + +void MainWindow::appendLogText(const QString &message) +{ + logDebug->append(message); +} + +void MainWindow::on_actionFileNew_triggered() +{ + QAxSelect select(this); + while (select.exec() && !addControlFromClsid(select.clsid())) { } } void MainWindow::on_actionFileLoad_triggered() { - QString fname = QFileDialog::getOpenFileName(this, tr("Load"), QString(), QLatin1String("*.qax")); - if (fname.isEmpty()) - return; + while (true) { + const QString fname = QFileDialog::getOpenFileName(this, tr("Load"), QString(), QLatin1String("*.qax")); + if (fname.isEmpty() || addControlFromFile(fname)) + break; + } +} - QFile file(fname); +bool MainWindow::addControlFromFile(const QString &fileName) +{ + QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { - QMessageBox::information(this, tr("Error Loading File"), tr("The file could not be opened for reading.\n%1").arg(fname)); - return; + QMessageBox::information(this, + tr("Error Loading File"), + tr("The file could not be opened for reading.\n%1\n%2") + .arg(QDir::toNativeSeparators(fileName), file.errorString())); + return false; } - QAxWidget *container = new QAxWidget(mdiArea); + QAxWidget *container = new QAxWidget(m_mdiArea); container->setObjectName(container->windowTitle()); QDataStream d(&file); d >> *container; - mdiArea->addSubWindow(container); + m_mdiArea->addSubWindow(container); container->show(); updateGUI(); + return true; } void MainWindow::on_actionFileSave_triggered() @@ -190,11 +232,11 @@ void MainWindow::on_actionContainerClear_triggered() void MainWindow::on_actionContainerProperties_triggered() { - if (!dlgAmbient) { - dlgAmbient = new AmbientProperties(this); - dlgAmbient->setControl(mdiArea); + if (!m_dlgAmbient) { + m_dlgAmbient = new AmbientProperties(this); + m_dlgAmbient->setControl(m_mdiArea); } - dlgAmbient->show(); + m_dlgAmbient->show(); } @@ -215,12 +257,12 @@ void MainWindow::on_actionControlProperties_triggered() if (!container) return; - if (!dlgProperties) { - dlgProperties = new ChangeProperties(this); - connect(container, SIGNAL(propertyChanged(QString)), dlgProperties, SLOT(updateProperties())); + if (!m_dlgProperties) { + m_dlgProperties = new ChangeProperties(this); + connect(container, SIGNAL(propertyChanged(QString)), m_dlgProperties, SLOT(updateProperties())); } - dlgProperties->setControl(container); - dlgProperties->show(); + m_dlgProperties->setControl(container); + m_dlgProperties->show(); } void MainWindow::on_actionControlMethods_triggered() @@ -229,10 +271,10 @@ void MainWindow::on_actionControlMethods_triggered() if (!container) return; - if (!dlgInvoke) - dlgInvoke = new InvokeMethod(this); - dlgInvoke->setControl(container); - dlgInvoke->show(); + if (!m_dlgInvoke) + m_dlgInvoke = new InvokeMethod(this); + m_dlgInvoke->setControl(container); + m_dlgInvoke->show(); } void MainWindow::on_VerbMenu_aboutToShow() @@ -273,7 +315,7 @@ void MainWindow::on_actionControlDocumentation_triggered() return; DocuWindow *docwindow = new DocuWindow(docu); - QMdiSubWindow *subWindow = mdiArea->addSubWindow(docwindow); + QMdiSubWindow *subWindow = m_mdiArea->addSubWindow(docwindow); subWindow->setWindowTitle(DocuWindow::tr("%1 - Documentation").arg(container->windowTitle())); docwindow->show(); } @@ -286,7 +328,7 @@ void MainWindow::on_actionControlPixmap_triggered() QLabel *label = new QLabel; label->setPixmap(QPixmap::grabWidget(container)); - QMdiSubWindow *subWindow = mdiArea->addSubWindow(label); + QMdiSubWindow *subWindow = m_mdiArea->addSubWindow(label); subWindow->setWindowTitle(tr("%1 - Pixmap").arg(container->windowTitle())); label->show(); } @@ -294,58 +336,75 @@ void MainWindow::on_actionControlPixmap_triggered() void MainWindow::on_actionScriptingRun_triggered() { #ifndef QT_NO_QAXSCRIPT - if (!scripts) + if (!m_scripts) return; // If we have only one script loaded we can use the cool dialog - QStringList scriptList = scripts->scriptNames(); + QStringList scriptList = m_scripts->scriptNames(); if (scriptList.count() == 1) { InvokeMethod scriptInvoke(this); scriptInvoke.setWindowTitle(tr("Execute Script Function")); - scriptInvoke.setControl(scripts->script(scriptList[0])->scriptEngine()); + scriptInvoke.setControl(m_scripts->script(scriptList[0])->scriptEngine()); scriptInvoke.exec(); return; } bool ok = false; - QStringList macroList = scripts->functions(QAxScript::FunctionNames); + QStringList macroList = m_scripts->functions(QAxScript::FunctionNames); QString macro = QInputDialog::getItem(this, tr("Select Macro"), tr("Macro:"), macroList, 0, true, &ok); if (!ok) return; - QVariant result = scripts->call(macro); + QVariant result = m_scripts->call(macro); if (result.isValid()) logMacros->append(tr("Return value of %1: %2").arg(macro).arg(result.toString())); #endif } +#ifdef QT_NO_QAXSCRIPT +static inline void noScriptMessage(QWidget *parent) +{ + QMessageBox::information(parent, MainWindow::tr("Function not available"), + MainWindow::tr("QAxScript functionality is not available with this compiler.")); +} +#endif // !QT_NO_QAXSCRIPT + void MainWindow::on_actionScriptingLoad_triggered() { #ifndef QT_NO_QAXSCRIPT QString file = QFileDialog::getOpenFileName(this, tr("Open Script"), QString(), QAxScriptManager::scriptFileFilter()); - if (file.isEmpty()) - return; + if (!file.isEmpty()) + loadScript(file); +#else // !QT_NO_QAXSCRIPT + noScriptMessage(this); +#endif +} - if (!scripts) { - scripts = new QAxScriptManager(this); - scripts->addObject(this); +bool MainWindow::loadScript(const QString &file) +{ +#ifndef QT_NO_QAXSCRIPT + if (!m_scripts) { + m_scripts = new QAxScriptManager(this); + m_scripts->addObject(this); } foreach (QAxWidget *axWidget, axWidgets()) { QAxBase *ax = axWidget; - scripts->addObject(ax); + m_scripts->addObject(ax); } - QAxScript *script = scripts->load(file, file); + QAxScript *script = m_scripts->load(file, file); if (script) { connect(script, &QAxScript::error, this, &MainWindow::logMacro); actionScriptingRun->setEnabled(true); } -#else - QMessageBox::information(this, tr("Function not available"), - tr("QAxScript functionality is not available with this compiler.")); + return script; +#else // !QT_NO_QAXSCRIPT + Q_UNUSED(file) + noScriptMessage(this); + return false; #endif } @@ -365,10 +424,10 @@ void MainWindow::updateGUI() actionControlDocumentation->setEnabled(hasControl); actionControlPixmap->setEnabled(hasControl); VerbMenu->setEnabled(hasControl); - if (dlgInvoke) - dlgInvoke->setControl(hasControl ? container : 0); - if (dlgProperties) - dlgProperties->setControl(hasControl ? container : 0); + if (m_dlgInvoke) + m_dlgInvoke->setControl(hasControl ? container : 0); + if (m_dlgProperties) + m_dlgProperties->setControl(hasControl ? container : 0); foreach (QAxWidget *container, axWidgets()) { container->disconnect(SIGNAL(signal(QString,int,void*))); diff --git a/tools/testcon/mainwindow.h b/tools/testcon/mainwindow.h index 68b85b1..a9d15dd 100644 --- a/tools/testcon/mainwindow.h +++ b/tools/testcon/mainwindow.h @@ -57,6 +57,18 @@ public: MainWindow(QWidget *parent = 0); ~MainWindow(); + static MainWindow *instance() { return m_instance; } + + bool addControlFromClsid(const QString &clsid); + bool addControlFromFile(const QString &fileName); + bool loadScript(const QString &file); + +protected: + void closeEvent(QCloseEvent *) Q_DECL_OVERRIDE; + +public slots: + void appendLogText(const QString &); + protected slots: void on_actionFileNew_triggered(); void on_actionFileLoad_triggered(); @@ -80,13 +92,15 @@ private: QAxWidget *activeAxWidget() const; QList<QAxWidget *> axWidgets() const; - InvokeMethod *dlgInvoke; - ChangeProperties *dlgProperties; - AmbientProperties *dlgAmbient; - QAxScriptManager *scripts; - QMdiArea *mdiArea; + static MainWindow *m_instance; + + InvokeMethod *m_dlgInvoke; + ChangeProperties *m_dlgProperties; + AmbientProperties *m_dlgAmbient; + QAxScriptManager *m_scripts; + QMdiArea *m_mdiArea; - QtMessageHandler oldDebugHandler; + QtMessageHandler m_oldDebugHandler; private slots: void updateGUI(); diff --git a/tools/testcon/mainwindow.ui b/tools/testcon/mainwindow.ui index da39df5..979092d 100644 --- a/tools/testcon/mainwindow.ui +++ b/tools/testcon/mainwindow.ui @@ -38,14 +38,6 @@ <property name="objectName" > <string notr="true" >MainWindow</string> </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>929</width> - <height>620</height> - </rect> - </property> <property name="windowTitle" > <string>ActiveX Control Test Container</string> </property> diff --git a/tools/testcon/scripts/hierarchyax.vbs b/tools/testcon/scripts/hierarchyax.vbs new file mode 100644 index 0000000..2340442 --- /dev/null +++ b/tools/testcon/scripts/hierarchyax.vbs @@ -0,0 +1,55 @@ +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +'' +'' Copyright (C) 2015 The Qt Company Ltd. +'' Contact: http://www.qt.io/licensing/ +'' +'' This file is part of the ActiveQt module of the Qt Toolkit. +'' +'' $QT_BEGIN_LICENSE:LGPL21$ +'' Commercial License Usage +'' Licensees holding valid commercial Qt licenses may use this file in +'' accordance with the commercial license agreement provided with the +'' Software or, alternatively, in accordance with the terms contained in +'' a written agreement between you and The Qt Company. For licensing terms +'' and conditions see http://www.qt.io/terms-conditions. For further +'' information use the contact form at http://www.qt.io/contact-us. +'' +'' GNU Lesser General Public License Usage +'' Alternatively, this file may be used under the terms of the GNU Lesser +'' General Public License version 2.1 or version 3 as published by the Free +'' Software Foundation and appearing in the file LICENSE.LGPLv21 and +'' LICENSE.LGPLv3 included in the packaging of this file. Please review the +'' following information to ensure the GNU Lesser General Public License +'' requirements will be met: https://www.gnu.org/licenses/lgpl.html and +'' http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +'' +'' As a special exception, The Qt Company gives you certain additional +'' rights. These rights are described in The Qt Company LGPL Exception +'' version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +'' +'' $QT_END_LICENSE$ +'' +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +' This script can be loaded in Qt TestCon, and used to script +' the hierarchyax project. +' +' Instructions: Open testcon, insert the QParentWidget class, +' load this script, run "Main()" macro. + +Sub Main + ' Create new widget object + QParentWidget.createSubWidget("ABC") + + ' Retrieve widget + Set widget = QParentWidget.subWidget("ABC") + + ' Read label property + label = widget.label + MainWindow.logMacro 0, "Old widget label: "&label, 0, "" + + ' Write label property + widget.label = "renamed "&label + label = widget.label + MainWindow.logMacro 0, "New widget label: "&label, 0, "" +End Sub |