summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2016-01-07 10:16:12 +0100
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2016-01-18 14:06:55 +0000
commit06276f3532750e1ecc51eac97b732cdd7258057e (patch)
tree7da9fa5411b19f52cd26d0827010dca7de4bc99b
parent2af645d0678afe0fa0ea214d0557c32bfbbdf93b (diff)
Adapt to High DPI scaling.
[ChangeLog] Adapt to High DPI scaling. Task-number: QTBUG-46615 Change-Id: Ic56a2ff4f3115ae7d2b9a63fd3a8f15dc9d71ebe Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
-rw-r--r--src/activeqt/container/qaxwidget.cpp39
-rw-r--r--src/activeqt/control/qaxserverbase.cpp41
-rw-r--r--src/activeqt/shared/qaxutils.cpp128
-rw-r--r--src/activeqt/shared/qaxutils_p.h48
4 files changed, 211 insertions, 45 deletions
diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp
index 987c649..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);
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/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 &region)
+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 &region)
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 &region, 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 &region);
+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 &region, const QWidget *widget);
+#endif // QT_WIDGETS_LIB
QT_END_NAMESPACE