diff options
-rw-r--r-- | src/activeqt/container/qaxbase.cpp | 2 | ||||
-rw-r--r-- | src/activeqt/container/qaxselect.cpp | 4 | ||||
-rw-r--r-- | src/activeqt/container/qaxselect.ui | 8 | ||||
-rw-r--r-- | src/activeqt/container/qaxwidget.cpp | 42 | ||||
-rw-r--r-- | src/activeqt/control/qaxfactory.h | 6 | ||||
-rw-r--r-- | src/activeqt/control/qaxserver.cpp | 2 | ||||
-rw-r--r-- | src/activeqt/control/qaxserverbase.cpp | 41 | ||||
-rw-r--r-- | src/activeqt/doc/activeqt.qdocconf | 4 | ||||
-rw-r--r-- | src/activeqt/shared/qaxutils.cpp | 128 | ||||
-rw-r--r-- | src/activeqt/shared/qaxutils_p.h | 48 | ||||
-rw-r--r-- | tests/manual/axviewer/axviewer.pro | 6 | ||||
-rw-r--r-- | tests/manual/axviewer/main.cpp | 171 | ||||
-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 |
16 files changed, 594 insertions, 148 deletions
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index b3c2b90..acc319e 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -3640,7 +3640,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) if (dispid == DISPID_UNKNOWN && slotname.toLower().startsWith("set")) { // see if we are calling a property set function as a slot - slotname.remove(0, slotname.length() - 3); + slotname.remove(0, 3); dispid = d->metaobj->dispIDofName(slotname, disp); isProperty = true; } 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/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp index a099bad..ae3e3e1 100644 --- a/src/activeqt/container/qaxwidget.cpp +++ b/src/activeqt/container/qaxwidget.cpp @@ -192,7 +192,7 @@ public: if (!host) return OLE_E_NOT_INPLACEACTIVE; - RECT rcPos = { host->x(), host->y(), host->x()+host->width(), host->y()+host->height() }; + RECT rcPos = qaxNativeWidgetRect(host); return m_spOleObject->DoVerb(index, 0, this, 0, (HWND)host->winId(), &rcPos); @@ -471,6 +471,8 @@ bool QAxNativeEventFilter::nativeEventFilter(const QByteArray &, void *m, long * { MSG *msg = (MSG*)m; const uint message = msg->message; + if (message == WM_DISPLAYCHANGE) + qaxClearCachedSystemLogicalDpi(); if ((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) || (message >= WM_KEYFIRST && message <= WM_KEYLAST)) { HWND hwnd = msg->hwnd; QAxWidget *ax = 0; @@ -508,7 +510,8 @@ bool QAxNativeEventFilter::nativeEventFilter(const QByteArray &, void *m, long * button = 0; DWORD ol_pos = GetMessagePos(); - QPoint gpos(GET_X_LPARAM(ol_pos), GET_Y_LPARAM(ol_pos)); + const QPoint nativeGlobalPos(GET_X_LPARAM(ol_pos), GET_Y_LPARAM(ol_pos)); + const QPoint gpos = qaxFromNativePosition(ax, nativeGlobalPos); QPoint pos = ax->mapFromGlobal(gpos); QMouseEvent e(type, pos, gpos, (Qt::MouseButton)button, @@ -662,15 +665,12 @@ bool QAxClientSite::activateObject(bool initialized, const QByteArray &data) m_spOleObject->SetHostNames(OLESTR("AXWIN"), 0); if (!(dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)) { - SIZEL hmSize; - hmSize.cx = MAP_PIX_TO_LOGHIM(250, widget->logicalDpiX()); - hmSize.cy = MAP_PIX_TO_LOGHIM(250, widget->logicalDpiY()); + SIZEL hmSize = qaxMapPixToLogHiMetrics(QSize(250, 250), widget); m_spOleObject->SetExtent(DVASPECT_CONTENT, &hmSize); m_spOleObject->GetExtent(DVASPECT_CONTENT, &hmSize); - sizehint.setWidth(MAP_LOGHIM_TO_PIX(hmSize.cx, widget->logicalDpiX())); - sizehint.setHeight(MAP_LOGHIM_TO_PIX(hmSize.cy, widget->logicalDpiY())); + sizehint = qaxMapLogHiMetricsToPix(hmSize, widget); showHost = true; } else { sizehint = QSize(0, 0); @@ -682,7 +682,7 @@ bool QAxClientSite::activateObject(bool initialized, const QByteArray &data) host->setFocusPolicy(Qt::NoFocus); } - RECT rcPos = { host->x(), host->y(), host->x()+sizehint.width(), host->y()+sizehint.height() }; + RECT rcPos = qaxQRect2Rect(QRect(qaxNativeWidgetPosition(host), qaxToNativeSize(host, sizehint))); m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, 0, (IOleClientSite*)this, 0, (HWND)host->winId(), @@ -1564,12 +1564,8 @@ QSize QAxClientSite::minimumSizeHint() const SIZE sz = { 0, 0 }; m_spOleObject->SetExtent(DVASPECT_CONTENT, &sz); - HRESULT res = m_spOleObject->GetExtent(DVASPECT_CONTENT, &sz); - if (SUCCEEDED(res)) { - return QSize(MAP_LOGHIM_TO_PIX(sz.cx, widget->logicalDpiX()), - MAP_LOGHIM_TO_PIX(sz.cy, widget->logicalDpiY())); - } - return QSize(); + return SUCCEEDED(m_spOleObject->GetExtent(DVASPECT_CONTENT, &sz)) + ? qaxMapLogHiMetricsToPix(sz, widget) : QSize(); } void QAxClientSite::windowActivationChange() @@ -1662,14 +1658,11 @@ void QAxHostWidget::resizeObject() return; } - SIZEL hmSize; - hmSize.cx = MAP_PIX_TO_LOGHIM(width(), logicalDpiX()); - hmSize.cy = MAP_PIX_TO_LOGHIM(height(), logicalDpiY()); - + SIZEL hmSize = qaxMapPixToLogHiMetrics(size(), this); if (axhost->m_spOleObject) axhost->m_spOleObject->SetExtent(DVASPECT_CONTENT, &hmSize); if (axhost->m_spInPlaceObject) { - RECT rcPos = { x(), y(), x()+width(), y()+height() }; + RECT rcPos = qaxNativeWidgetRect(this); axhost->m_spInPlaceObject->SetObjectRects(&rcPos, &rcPos); } } @@ -1709,7 +1702,7 @@ bool QAxHostWidget::event(QEvent *e) if (axhost && ((QTimerEvent*)e)->timerId() == setFocusTimer) { killTimer(setFocusTimer); setFocusTimer = 0; - RECT rcPos = { x(), y(), x()+size().width(), y()+size().height() }; + RECT rcPos = qaxNativeWidgetRect(this); axhost->m_spOleObject->DoVerb(OLEIVERB_UIACTIVATE, 0, (IOleClientSite*)axhost, 0, (HWND)winId(), &rcPos); @@ -1801,7 +1794,7 @@ void QAxHostWidget::paintEvent(QPaintEvent*) if (!view) return; - QPixmap pm(size()); + QPixmap pm(qaxNativeWidgetSize(this)); pm.fill(); HBITMAP hBmp = qaxPixmapToWinHBITMAP(pm); @@ -1818,7 +1811,9 @@ void QAxHostWidget::paintEvent(QPaintEvent*) view->Release(); QPainter painter(this); - painter.drawPixmap(0, 0, qaxPixmapFromWinHBITMAP(hBmp)); + QPixmap pixmap = qaxPixmapFromWinHBITMAP(hBmp); + pixmap.setDevicePixelRatio(devicePixelRatioF()); + painter.drawPixmap(0, 0, pixmap); SelectObject(hBmp_hdc, old_hBmp); DeleteObject(hBmp); @@ -1965,8 +1960,9 @@ bool QAxWidget::createHostWindow(bool initialized) */ bool QAxWidget::createHostWindow(bool initialized, const QByteArray &data) { + if (!container) // Potentially called repeatedly from QAxBase::metaObject(), QAxWidget::initialize() + container = new QAxClientSite(this); - container = new QAxClientSite(this); container->activateObject(initialized, data); ATOM filter_ref = FindAtom(qaxatom); diff --git a/src/activeqt/control/qaxfactory.h b/src/activeqt/control/qaxfactory.h index 8f9b30e..e5745f8 100644 --- a/src/activeqt/control/qaxfactory.h +++ b/src/activeqt/control/qaxfactory.h @@ -190,7 +190,7 @@ public: {} const QMetaObject *metaObject(const QString &) const Q_DECL_OVERRIDE { return &T::staticMetaObject; } - QStringList featureList() const Q_DECL_OVERRIDE { return QStringList(QString(T::staticMetaObject.className())); } + QStringList featureList() const Q_DECL_OVERRIDE { return QStringList(QLatin1String(T::staticMetaObject.className())); } QObject *createObject(const QString &key) Q_DECL_OVERRIDE { const QMetaObject &mo = T::staticMetaObject; @@ -251,7 +251,7 @@ private: 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); \ @@ -261,7 +261,7 @@ private: 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 5efdae9..b1eac89 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -346,10 +346,8 @@ public: RECT rcPosRect() const { RECT result = {0, 0, 1, 1}; - if (qt.widget) { - result.right = qt.widget->width() + 1; - result.bottom = qt.widget->height() + 1; - } + if (qt.widget) + result = qaxContentRect(QSize(1, 1) + qaxNativeWidgetSize(qt.widget)); return result; } @@ -419,7 +417,7 @@ private: IOleInPlaceFrame *m_spInPlaceFrame; ITypeInfo *m_spTypeInfo; IStorage *m_spStorage; - QSize m_currentExtent; + QSize m_currentExtent; // device independent pixels. }; static inline QAxServerBase *axServerBaseFromWindow(HWND hWnd) @@ -1447,7 +1445,7 @@ LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM case WM_SIZE: if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) - that->resize(QSize(LOWORD(lParam), HIWORD(lParam))); + that->resize(qaxFromNativeSize(that->qt.widget, QSize(LOWORD(lParam), HIWORD(lParam)))); break; case WM_SETFOCUS: @@ -1563,6 +1561,9 @@ LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM } break; + case WM_DISPLAYCHANGE: + qaxClearCachedSystemLogicalDpi(); + default: break; } @@ -1868,7 +1869,7 @@ void QAxServerBase::updateMask() return; QRegion rgn = qt.widget->mask(); - HRGN hrgn = qaxHrgnFromQRegion(rgn); + HRGN hrgn = qaxHrgnFromQRegion(rgn, qt.widget); // Since SetWindowRegion takes ownership HRGN wr = CreateRectRgn(0,0,0,0); @@ -2636,11 +2637,10 @@ HRESULT WINAPI QAxServerBase::Invoke(DISPID dispidMember, REFIID riid, exception = 0; return DISP_E_EXCEPTION; } else if (isWidget) { - QSize sizeHint = qt.widget->sizeHint(); - if (oldSizeHint != sizeHint) { + if (oldSizeHint != qt.widget->sizeHint()) { updateGeometry(); if (m_spInPlaceSite) { - RECT rect = {0, 0, sizeHint.width(), sizeHint.height()}; + RECT rect = qaxContentRect(qaxToNativeSize(qt.widget, qt.widget->sizeHint())); m_spInPlaceSite->OnPosRectChange(&rect); } } @@ -3474,8 +3474,9 @@ HRESULT WINAPI QAxServerBase::SetObjectRects(LPCRECT prcPos, LPCRECT prcClip) } //Save the new extent. - m_currentExtent.rwidth() = qBound(qt.widget->minimumWidth(), int(prcPos->right - prcPos->left), qt.widget->maximumWidth()); - m_currentExtent.rheight() = qBound(qt.widget->minimumHeight(), int(prcPos->bottom - prcPos->top), qt.widget->maximumHeight()); + const QRect qr = qaxFromNativeRect(*prcPos, qt.widget); + m_currentExtent.rwidth() = qBound(qt.widget->minimumWidth(), qr.width(), qt.widget->maximumWidth()); + m_currentExtent.rheight() = qBound(qt.widget->minimumHeight(), qr.height(), qt.widget->maximumHeight()); return S_OK; } @@ -3944,8 +3945,7 @@ HRESULT WINAPI QAxServerBase::GetExtent(DWORD dwDrawAspect, SIZEL* psizel) if (!psizel) return E_POINTER; - psizel->cx = MAP_PIX_TO_LOGHIM(m_currentExtent.width(), qt.widget->logicalDpiX()); - psizel->cy = MAP_PIX_TO_LOGHIM(m_currentExtent.height(), qt.widget->logicalDpiY()); + *psizel = qaxMapPixToLogHiMetrics(m_currentExtent, qt.widget); return S_OK; } @@ -4034,8 +4034,7 @@ HRESULT WINAPI QAxServerBase::SetExtent(DWORD dwDrawAspect, SIZEL* psizel) if (!isWidget || !qt.widget) // nothing to do return S_OK; - QSize proposedSize(MAP_LOGHIM_TO_PIX(psizel->cx, qt.widget->logicalDpiX()), - MAP_LOGHIM_TO_PIX(psizel->cy, qt.widget->logicalDpiY())); + QSize proposedSize(qaxMapLogHiMetricsToPix(*psizel, qt.widget)); // can the widget be resized at all? if (qt.widget->minimumSize() == qt.widget->maximumSize() && qt.widget->minimumSize() != proposedSize) @@ -4112,8 +4111,7 @@ HRESULT WINAPI QAxServerBase::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmediu HRESULT hres = m_spInPlaceSite->GetWindowContext(&m_spInPlaceFrame, &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo); if (hres == S_OK) { - QSize size(rcPos.right - rcPos.left, rcPos.bottom - rcPos.top); - resize(size); + resize(qaxFromNativeSize(qt.widget, qaxSizeOfRect(rcPos))); } else { qt.widget->adjustSize(); } @@ -4145,8 +4143,9 @@ HRESULT WINAPI QAxServerBase::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmediu LPMETAFILEPICT pMF = (LPMETAFILEPICT)GlobalLock(hMem); pMF->hMF = hMF; pMF->mm = MM_ANISOTROPIC; - pMF->xExt = MAP_PIX_TO_LOGHIM(width, qt.widget->logicalDpiX()); - pMF->yExt = MAP_PIX_TO_LOGHIM(height, qt.widget->logicalDpiY()); + const SIZEL sizeL = qaxMapPixToLogHiMetrics(QSize(width, height), qt.widget); + pMF->xExt = sizeL.cx; + pMF->yExt = sizeL.cy; GlobalUnlock(hMem); memset(pmedium, 0, sizeof(STGMEDIUM)); @@ -4267,7 +4266,7 @@ bool QAxServerBase::eventFilter(QObject *o, QEvent *e) } updateGeometry(); if (m_spInPlaceSite && qt.widget->sizeHint().isValid()) { - RECT rect = {0, 0, qt.widget->sizeHint().width(), qt.widget->sizeHint().height()}; + RECT rect = qaxContentRect(qaxToNativeSize(qt.widget, qt.widget->sizeHint())); m_spInPlaceSite->OnPosRectChange(&rect); } } diff --git a/src/activeqt/doc/activeqt.qdocconf b/src/activeqt/doc/activeqt.qdocconf index df3175b..2d41e63 100644 --- a/src/activeqt/doc/activeqt.qdocconf +++ b/src/activeqt/doc/activeqt.qdocconf @@ -21,12 +21,12 @@ qhp.ActiveQt.customFilters.Qt.filterAttributes = activeqt $QT_VERSION qhp.ActiveQt.subprojects = qaxcontainerclasses qaxserverclasses qhp.ActiveQt.subprojects.qaxcontainerclasses.title = QAxContainer C++ Classes qhp.ActiveQt.subprojects.qaxcontainerclasses.indexTitle = QAxContainer C++ Classes -qhp.ActiveQt.subprojects.qaxcontainerclasses.selectors = class fake:headerfile +qhp.ActiveQt.subprojects.qaxcontainerclasses.selectors = module:QAxContainer qhp.ActiveQt.subprojects.qaxcontainerclasses.sortPages = true qhp.ActiveQt.subprojects.qaxserverclasses.title = QAxServer C++ Classes qhp.ActiveQt.subprojects.qaxserverclasses.indexTitle = QAxServer C++ Classes -qhp.ActiveQt.subprojects.qaxserverclasses.selectors = class fake:headerfile +qhp.ActiveQt.subprojects.qaxserverclasses.selectors = module:QAxServer qhp.ActiveQt.subprojects.qaxserverclasses.sortPages = true tagfile = ../../../doc/activeqt/activeqt.tags diff --git a/src/activeqt/shared/qaxutils.cpp b/src/activeqt/shared/qaxutils.cpp index 7e5a9be..9f94835 100644 --- a/src/activeqt/shared/qaxutils.cpp +++ b/src/activeqt/shared/qaxutils.cpp @@ -45,6 +45,7 @@ #include <QtGui/QRegion> #include <QtGui/QWindow> #include <QtGui/QGuiApplication> +#include <private/qhighdpiscaling_p.h> #include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformpixmap.h> #include <QtGui/private/qpixmap_raster_p.h> @@ -208,8 +209,9 @@ static void addRectToHrgn(HRGN &winRegion, const QRect &r) } } -HRGN qaxHrgnFromQRegion(const QRegion ®ion) +HRGN qaxHrgnFromQRegion(QRegion region, const QWindow *window) { + region = QHighDpi::toNativeLocalRegion(region, window); HRGN hRegion = CreateRectRgn(0, 0, 0, 0); if (region.rectCount() == 1) { addRectToHrgn(hRegion, region.boundingRect()); @@ -220,4 +222,128 @@ HRGN qaxHrgnFromQRegion(const QRegion ®ion) return hRegion; } +// HIMETRICS scaling +static const qreal himetricsPerInch = 2540; + +static inline long qaxMapPixToLogHiMetrics(int x, qreal logicalDpi, qreal factor) +{ + return qRound((qreal(x) * himetricsPerInch * factor) / logicalDpi); +} + +static inline int qaxMapLogHiMetricsToPix(long x, qreal logicalDpi, qreal factor) +{ + return qRound(logicalDpi * qreal(x) / (himetricsPerInch * factor)); +} + +SIZEL qaxMapPixToLogHiMetrics(const QSize &s, const QDpi &d, const QWindow *w) +{ + const qreal factor = QHighDpiScaling::factor(w); + const SIZEL result = { + qaxMapPixToLogHiMetrics(s.width(), d.first, factor), + qaxMapPixToLogHiMetrics(s.height(), d.second, factor) + }; + return result; +} + +QSize qaxMapLogHiMetricsToPix(const SIZEL &s, const QDpi &d, const QWindow *w) +{ + const qreal factor = QHighDpiScaling::factor(w); + const QSize result(qaxMapLogHiMetricsToPix(s.cx, d.first, factor), + qaxMapLogHiMetricsToPix(s.cy, d.second, factor)); + return result; +} + +// Cache logical DPI in case High DPI scaling is active (which case +// the fake logical DPI it calculates is not suitable). + +static QDpi cachedSystemLogicalDpi(-1, -1); + +void qaxClearCachedSystemLogicalDpi() // Call from WM_DISPLAYCHANGE +{ + cachedSystemLogicalDpi = QDpi(-1, -1); +} + +static inline QDpi systemLogicalDpi() +{ + if (cachedSystemLogicalDpi.first < 0) { + const HDC displayDC = GetDC(0); + cachedSystemLogicalDpi = QDpi(GetDeviceCaps(displayDC, LOGPIXELSX), GetDeviceCaps(displayDC, LOGPIXELSY)); + ReleaseDC(0, displayDC); + } + return cachedSystemLogicalDpi; +} + +static inline QDpi paintDeviceLogicalDpi(const QPaintDevice *d) +{ + return QDpi(d->logicalDpiX(), d->logicalDpiY()); +} + +#ifdef QT_WIDGETS_LIB + +SIZEL qaxMapPixToLogHiMetrics(const QSize &s, const QWidget *widget) +{ + return qaxMapPixToLogHiMetrics(s, + QHighDpiScaling::isActive() ? systemLogicalDpi() : paintDeviceLogicalDpi(widget), + widget->windowHandle()); +} + +QSize qaxMapLogHiMetricsToPix(const SIZEL &s, const QWidget *widget) +{ + return qaxMapLogHiMetricsToPix(s, + QHighDpiScaling::isActive() ? systemLogicalDpi() : paintDeviceLogicalDpi(widget), + widget->windowHandle()); +} + +QPoint qaxFromNativePosition(const QWidget *w, const QPoint &nativePos) +{ + const qreal factor = QHighDpiScaling::factor(w->windowHandle()); + return qFuzzyCompare(factor, 1) + ? nativePos : (QPointF(nativePos) / factor).toPoint(); +} + +QPoint qaxNativeWidgetPosition(const QWidget *w) +{ + return qaxFromNativePosition(w, w->geometry().topLeft()); +} + +QSize qaxToNativeSize(const QWidget *w, const QSize &size) +{ + const qreal factor = QHighDpiScaling::factor(w->windowHandle()); + return qFuzzyCompare(factor, 1) ? size : (QSizeF(size) * factor).toSize(); +} + +QSize qaxNativeWidgetSize(const QWidget *w) +{ + return qaxToNativeSize(w, w->size()); +} + +QSize qaxFromNativeSize(const QWidget *w, const QSize &size) +{ + const qreal factor = QHighDpiScaling::factor(w->windowHandle()); + return qFuzzyCompare(factor, 1) ? size : (QSizeF(size) / factor).toSize(); +} + +RECT qaxNativeWidgetRect(const QWidget *w) +{ + return QHighDpiScaling::isActive() + ? qaxQRect2Rect(QRect(qaxNativeWidgetPosition(w), qaxNativeWidgetSize(w))) + : qaxQRect2Rect(w->geometry()); +} + +QRect qaxFromNativeRect(const RECT &r, const QWidget *w) +{ + const QRect qr = qaxRect2QRect(r); + const qreal factor = QHighDpiScaling::factor(w->windowHandle()); + return qFuzzyCompare(factor, 1) + ? qr + : QRect((QPointF(qr.topLeft()) / factor).toPoint(), (QSizeF(qr.size()) / factor).toSize()); +} + +HRGN qaxHrgnFromQRegion(const QRegion ®ion, const QWidget *widget) +{ + return qaxHrgnFromQRegion(region, widget->windowHandle()); +} + +#endif // QT_WIDGETS_LIB + QT_END_NAMESPACE diff --git a/src/activeqt/shared/qaxutils_p.h b/src/activeqt/shared/qaxutils_p.h index 75a4c89..acd0eb8 100644 --- a/src/activeqt/shared/qaxutils_p.h +++ b/src/activeqt/shared/qaxutils_p.h @@ -54,6 +54,8 @@ #include <QtCore/qt_windows.h> #include <QtCore/QMetaType> +#include <QtCore/QPair> +#include <QtCore/QRect> QT_BEGIN_NAMESPACE @@ -61,6 +63,7 @@ class QWidget; class QPixmap; class QRect; class QRegion; +class QWindow; enum HBitmapFormat { @@ -72,7 +75,50 @@ enum HBitmapFormat HWND hwndForWidget(QWidget *widget); HBITMAP qaxPixmapToWinHBITMAP(const QPixmap &p, HBitmapFormat format = HBitmapNoAlpha); QPixmap qaxPixmapFromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format = HBitmapNoAlpha); -HRGN qaxHrgnFromQRegion(const QRegion ®ion); +HRGN qaxHrgnFromQRegion(QRegion region, const QWindow *window); + +typedef QPair<qreal, qreal> QDpi; + +extern SIZEL qaxMapPixToLogHiMetrics(const QSize &s, const QDpi &d, const QWindow *w); +extern QSize qaxMapLogHiMetricsToPix(const SIZEL &s, const QDpi &d, const QWindow *w); + +void qaxClearCachedSystemLogicalDpi(); // Call from WM_DISPLAYCHANGE + +static inline RECT qaxQRect2Rect(const QRect &r) +{ + RECT result = { r.x(), r.y(), r.x() + r.width(), r.y() + r.height() }; + return result; +} + +static inline QSize qaxSizeOfRect(const RECT &rect) +{ + return QSize(rect.right -rect.left, rect.bottom - rect.top); +} + +static inline QRect qaxRect2QRect(const RECT &rect) +{ + return QRect(QPoint(rect.left, rect.top), qaxSizeOfRect(rect)); +} + +static inline RECT qaxContentRect(const QSize &size) // Size with topleft = 0,0 +{ + RECT result = { 0, 0, size.width(), size.height() }; + return result; +} + +#ifdef QT_WIDGETS_LIB +SIZEL qaxMapPixToLogHiMetrics(const QSize &s, const QWidget *widget); +QSize qaxMapLogHiMetricsToPix(const SIZEL &s, const QWidget *widget); + +QPoint qaxFromNativePosition(const QWidget *w, const QPoint &nativePos); +QPoint qaxNativeWidgetPosition(const QWidget *w); +QSize qaxToNativeSize(const QWidget *w, const QSize &size); +QSize qaxFromNativeSize(const QWidget *w, const QSize &size); +QSize qaxNativeWidgetSize(const QWidget *w); +RECT qaxNativeWidgetRect(const QWidget *w); +QRect qaxFromNativeRect(const RECT &r, const QWidget *w); +HRGN qaxHrgnFromQRegion(const QRegion ®ion, const QWidget *widget); +#endif // QT_WIDGETS_LIB QT_END_NAMESPACE diff --git a/tests/manual/axviewer/axviewer.pro b/tests/manual/axviewer/axviewer.pro new file mode 100644 index 0000000..2c06290 --- /dev/null +++ b/tests/manual/axviewer/axviewer.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +QT = core gui widgets axcontainer +CONFIG += console c++11 +SOURCES += main.cpp +DIAGLIB = ../../../../qtbase/tests/manual/diaglib +exists($$DIAGLIB):include($$DIAGLIB/diaglib.pri) diff --git a/tests/manual/axviewer/main.cpp b/tests/manual/axviewer/main.cpp new file mode 100644 index 0000000..34e6aa6 --- /dev/null +++ b/tests/manual/axviewer/main.cpp @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +#include <ActiveQt/QAxSelect> +#include <ActiveQt/QAxWidget> + +#include <QtWidgets/QAction> +#include <QtWidgets/QApplication> +#include <QtWidgets/QMainWindow> +#include <QtWidgets/QMenu> +#include <QtWidgets/QMenuBar> +#include <QtWidgets/QStatusBar> +#include <QtWidgets/QToolBar> + +#include <QtCore/QCommandLineOption> +#include <QtCore/QCommandLineParser> +#include <QtCore/QDebug> +#include <QtCore/QStringList> +#include <QtCore/QSysInfo> + +#ifdef QT_DIAG_LIB +# include <qwidgetdump.h> +# include <nativewindowdump.h> +# include <qwindowdump.h> +#endif + +#include <algorithm> +#include <iterator> + +QT_USE_NAMESPACE + +static inline bool isOptionSet(int argc, char *argv[], const char *option) +{ + return (argv + argc) != + std::find_if(argv + 1, argv + argc, + [option] (const char *arg) { return !qstrcmp(arg, option); }); +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(); + bool setControl(const QString &clsid); + +private: + QAxWidget *m_axWidget; +}; + +MainWindow::MainWindow() + : m_axWidget(new QAxWidget) +{ + const QString title = QGuiApplication::applicationDisplayName() + QLatin1String(" Qt ") + + QLatin1String(QT_VERSION_STR) + QLatin1String(", ") + + QString::number(QSysInfo::WordSize) + QLatin1String("bit"); + setWindowTitle(title); + + setObjectName(QLatin1String("MainWindow")); + m_axWidget->setObjectName(QLatin1String("AxWidget")); + + setCentralWidget(m_axWidget); + + QMenu *fileMenu = menuBar()->addMenu(QLatin1String("File")); + fileMenu->setObjectName(QLatin1String("FileMenu")); + QToolBar *toolbar = new QToolBar; + toolbar->setObjectName(QLatin1String("ToolBar")); + addToolBar(Qt::TopToolBarArea, toolbar); + + QAction *action; +#ifdef QT_DIAG_LIB + action = fileMenu->addAction("Dump Widgets", + this, [] () { QtDiag::dumpAllWidgets(); }); + toolbar->addAction(action); + action = fileMenu->addAction("Dump Windows", + this, [] () { QtDiag::dumpAllWindows(); }); + toolbar->addAction(action); + action = fileMenu->addAction("Dump Native Windows", + this, [this] () { QtDiag::dumpNativeWindows(winId()); }); + toolbar->addAction(action); + fileMenu->addSeparator(); +#endif // QT_DIAG_LIB + action = fileMenu->addAction("Quit", qApp, &QCoreApplication::quit); + toolbar->addAction(action); + action->setShortcut(Qt::CTRL + Qt::Key_Q); +} + +bool MainWindow::setControl(const QString &clsid) +{ + const bool result = m_axWidget->setControl(clsid); + if (result) + statusBar()->showMessage(QLatin1String("Loaded ") + clsid); + return result; +} + +int main(int argc, char* argv[]) +{ + if (isOptionSet(argc, argv, "-s")) + QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); + if (!isOptionSet(argc, argv, "-n")) + QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); + + QApplication app(argc, argv); + QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); + QGuiApplication::setApplicationName("Ax Viewer"); + + QCommandLineParser parser; + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption noScalingDummy(QStringLiteral("s"), + QStringLiteral("Set Qt::AA_DisableHighDpiScaling.")); + parser.addOption(noScalingDummy); + QCommandLineOption nativeSiblingsDummy(QStringLiteral("n"), + QStringLiteral("Do not set Qt::AA_DontCreateNativeWidgetSiblings.")); + parser.addOption(nativeSiblingsDummy); + parser.addPositionalArgument(QStringLiteral("[clsid]"), QStringLiteral("Class ID")); + + parser.process(QCoreApplication::arguments()); + + QString clsid = parser.positionalArguments().value(0, QString()); + if (clsid.isEmpty()) { + QAxSelect select; + if (select.exec() != QDialog::Accepted) + return 0; + clsid = select.clsid(); + } + + MainWindow mainWindow; + + qDebug() << QT_VERSION_STR << "Loading" << clsid; + + if (!mainWindow.setControl(clsid)) { + qWarning().noquote().nospace() << "Failed to set \"" << clsid << '"'; + return -1; + } + + mainWindow.show(); + return app.exec(); +} + +#include "main.moc" 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> |