summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore160
-rw-r--r--.qmake.conf2
-rw-r--r--src/activeqt/container/qaxselect.cpp4
-rw-r--r--src/activeqt/container/qaxselect.ui8
-rw-r--r--src/activeqt/control/control.pro2
-rw-r--r--src/activeqt/control/qaxfactory.h4
-rw-r--r--src/activeqt/control/qaxserver.cpp2
-rw-r--r--src/activeqt/control/qaxserverbase.cpp155
-rw-r--r--src/activeqt/control/qaxservermain.cpp26
-rw-r--r--src/activeqt/doc/activeqt.qdocconf2
-rw-r--r--src/activeqt/doc/src/activeqt-index.qdoc2
-rw-r--r--src/activeqt/doc/src/qtaxserver.qdoc12
-rw-r--r--src/tools/idc/main.cpp150
-rw-r--r--tools/dumpcpp/main.cpp11
-rw-r--r--tools/testcon/main.cpp41
-rw-r--r--tools/testcon/mainwindow.cpp205
-rw-r--r--tools/testcon/mainwindow.h26
-rw-r--r--tools/testcon/mainwindow.ui8
-rw-r--r--tools/testcon/scripts/hierarchyax.vbs55
19 files changed, 471 insertions, 404 deletions
diff --git a/.gitignore b/.gitignore
index 6241b74..2de9614 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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