From f9f04ea63d2489bd2ecb91c5a6bee4c4a869ac20 Mon Sep 17 00:00:00 2001 From: Olli Werwolff Date: Thu, 7 Jul 2011 09:07:19 +0200 Subject: [PATCH] Use PlatformNativeInterface to obtain handles Change-Id: I8cdf3d5477e72e89bcde46ccb6670320bf4dd797 Reviewed-on: http://codereview.qt.nokia.com/1270 Reviewed-by: Qt Sanity Bot Reviewed-by: Friedemann Kleint --- src/gui/kernel/qwindowdefs_win.h | 2 +- src/widgets/dialogs/dialogs.pri | 4 ++- src/widgets/dialogs/qfiledialog_win.cpp | 9 +++--- src/widgets/dialogs/qwizard_win.cpp | 28 +++++++++++------ src/widgets/kernel/qapplication_p.h | 10 ++++++ src/widgets/kernel/qapplication_qpa.cpp | 19 +++++++++++- src/widgets/styles/qwindowsvistastyle.cpp | 5 ++- src/widgets/styles/qwindowsxpstyle.cpp | 37 +++++++++++++++++++---- 8 files changed, 91 insertions(+), 23 deletions(-) diff --git a/src/gui/kernel/qwindowdefs_win.h b/src/gui/kernel/qwindowdefs_win.h index fbcc73ad2a..2bf9c8e672 100644 --- a/src/gui/kernel/qwindowdefs_win.h +++ b/src/gui/kernel/qwindowdefs_win.h @@ -121,7 +121,7 @@ QT_BEGIN_NAMESPACE Q_CORE_EXPORT HINSTANCE qWinAppInst(); Q_CORE_EXPORT HINSTANCE qWinAppPrevInst(); Q_CORE_EXPORT int qWinAppCmdShow(); -Q_GUI_EXPORT HDC qt_win_display_dc(); +Q_WIDGETS_EXPORT HDC qt_win_display_dc(); QT_END_NAMESPACE diff --git a/src/widgets/dialogs/dialogs.pri b/src/widgets/dialogs/dialogs.pri index 472787a20c..fdbca9122f 100644 --- a/src/widgets/dialogs/dialogs.pri +++ b/src/widgets/dialogs/dialogs.pri @@ -50,6 +50,8 @@ HEADERS += \ } win32 { + qpa:DEFINES += QT_NO_PRINTDIALOG + HEADERS += dialogs/qwizard_win_p.h \ dialogs/qfiledialog_win_p.h SOURCES += dialogs/qdialogsbinarycompat_win.cpp \ @@ -61,7 +63,7 @@ win32 { !win32-borland:!wince*: LIBS += -lshell32 # the filedialog needs this library } -!mac:!symbian:unix|qpa { +!mac:!symbian:unix|qpa:!win32 { HEADERS += dialogs/qpagesetupdialog_unix_p.h SOURCES += dialogs/qprintdialog_unix.cpp \ dialogs/qpagesetupdialog_unix.cpp diff --git a/src/widgets/dialogs/qfiledialog_win.cpp b/src/widgets/dialogs/qfiledialog_win.cpp index de8e33d897..cdf8cd39cf 100644 --- a/src/widgets/dialogs/qfiledialog_win.cpp +++ b/src/widgets/dialogs/qfiledialog_win.cpp @@ -54,6 +54,7 @@ #include #include #include "qfiledialog_win_p.h" +#include "qplatformnativeinterface_qpa.h" #ifndef QT_NO_THREAD # include @@ -217,7 +218,7 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent, memset(ofn, 0, sizeof(OPENFILENAME)); ofn->lStructSize = sizeof(OPENFILENAME); - ofn->hwndOwner = parent ? parent->winId() : 0; + ofn->hwndOwner = QApplicationPrivate::getHWNDForWidget(parent); ofn->lpstrFilter = (wchar_t*)tFilters.utf16(); ofn->lpstrFile = tInitSel; ofn->nMaxFile = maxLen; @@ -522,7 +523,7 @@ static QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args, else parentWindow = QApplication::activeWindow(); // Show the file dialog. - hr = pfd->Show(parentWindow ? parentWindow->winId() : 0); + hr = pfd->Show(QApplicationPrivate::getHWNDForWidget(parentWindow)); if (SUCCEEDED(hr)) { // Retrieve the results. IShellItemArray *psiaResults; @@ -611,7 +612,7 @@ QString qt_win_CID_get_existing_directory(const QFileDialogArgs &args) parentWindow = QApplication::activeWindow(); // Show the file dialog. - hr = pfd->Show(parentWindow ? parentWindow->winId() : 0); + hr = pfd->Show(QApplicationPrivate::getHWNDForWidget(parentWindow)); if (SUCCEEDED(hr)) { // Retrieve the result IShellItem *psi = 0; @@ -786,7 +787,7 @@ QString qt_win_get_existing_directory(const QFileDialogArgs &args) qt_BROWSEINFO bi; Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); - bi.hwndOwner = (parent ? parent->winId() : 0); + bi.hwndOwner = QApplicationPrivate::getHWNDForWidget(parent); bi.pidlRoot = NULL; //### This does not seem to be respected? - the dialog always displays "Browse for folder" bi.lpszTitle = (wchar_t*)tTitle.utf16(); diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 32fc3dfe46..ab59e0109a 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -44,6 +44,8 @@ #include "qwizard_win_p.h" #include +#include +#include "qplatformnativeinterface_qpa.h" #include "qwizard.h" #include "qpaintengine.h" #include "qapplication.h" @@ -286,7 +288,8 @@ QVistaHelper::VistaState QVistaHelper::vistaState() QColor QVistaHelper::basicWindowFrameColor() { DWORD rgb; - HANDLE hTheme = pOpenThemeData(QApplication::desktop()->winId(), L"WINDOW"); + HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop()); + HANDLE hTheme = pOpenThemeData(handle, L"WINDOW"); pGetThemeColor( hTheme, WIZ_WP_CAPTION, WIZ_CS_ACTIVE, wizard->isActiveWindow() ? WIZ_TMT_FILLCOLORHINT : WIZ_TMT_BORDERCOLORHINT, @@ -306,7 +309,8 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type) mar.cyTopHeight = 0; else mar.cyTopHeight = titleBarSize() + topOffset(); - HRESULT hr = pDwmExtendFrameIntoClientArea(wizard->winId(), &mar); + HWND wizardHandle = QApplicationPrivate::getHWNDForWidget(wizard); + HRESULT hr = pDwmExtendFrameIntoClientArea(wizardHandle, &mar); value = SUCCEEDED(hr); } return value; @@ -314,7 +318,7 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type) void QVistaHelper::drawTitleBar(QPainter *painter) { - HDC hdc = painter->paintEngine()->getDC(); + HDC hdc = static_cast(painter->paintEngine())->getDC(); if (vistaState() == VistaAero) drawBlackRect(QRect(0, 0, wizard->width(), @@ -360,7 +364,8 @@ void QVistaHelper::setTitleBarIconAndCaptionVisible(bool visible) opt.dwMask = 0; else opt.dwMask = WIZ_WTNCA_NODRAWICON | WIZ_WTNCA_NODRAWCAPTION; - pSetWindowThemeAttribute(wizard->winId(), WIZ_WTA_NONCLIENT, &opt, sizeof(WIZ_WTA_OPTIONS)); + HWND handle = QApplicationPrivate::getHWNDForWidget(wizard); + pSetWindowThemeAttribute(handle, WIZ_WTA_NONCLIENT, &opt, sizeof(WIZ_WTA_OPTIONS)); } } @@ -437,7 +442,8 @@ void QVistaHelper::setWindowPosHack() const int y = wizard->geometry().y(); // ignored by SWP_NOMOVE const int w = wizard->width(); const int h = wizard->height(); - SetWindowPos(wizard->winId(), 0, x, y, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); + HWND handle = QApplicationPrivate::getHWNDForWidget(wizard); + SetWindowPos(handle, 0, x, y, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); } // The following hack allows any QWidget subclass to access @@ -575,7 +581,8 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event) msg.message = WM_NCHITTEST; msg.wParam = 0; msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY()); - msg.hwnd = wizard->winId(); + HWND handle = QApplicationPrivate::getHWNDForWidget(wizard); + msg.hwnd = handle; winEvent(&msg, &result); msg.wParam = result; msg.message = WM_NCMOUSEMOVE; @@ -587,7 +594,8 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event) msg.message = WM_NCHITTEST; msg.wParam = 0; msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY()); - msg.hwnd = wizard->winId(); + HWND handle = QApplicationPrivate::getHWNDForWidget(wizard); + msg.hwnd = handle; winEvent(&msg, &result); msg.wParam = result; msg.message = WM_NCLBUTTONDOWN; @@ -599,7 +607,8 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event) msg.message = WM_NCHITTEST; msg.wParam = 0; msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY()); - msg.hwnd = wizard->winId(); + HWND handle = QApplicationPrivate::getHWNDForWidget(wizard); + msg.hwnd = handle; winEvent(&msg, &result); msg.wParam = result; msg.message = WM_NCLBUTTONUP; @@ -628,7 +637,8 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q { bool value = false; if (vistaState() == VistaAero) { - HANDLE hTheme = pOpenThemeData(QApplication::desktop()->winId(), L"WINDOW"); + HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop()); + HANDLE hTheme = pOpenThemeData(handle, L"WINDOW"); if (!hTheme) return false; // Set up a memory DC and bitmap that we'll draw into HDC dcMem; diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 75cc003a1d..c4a9a15064 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -59,6 +59,9 @@ #include "QtGui/qfont.h" #include "QtGui/qcursor.h" #include "QtGui/qregion.h" +#include "QtGui/qwindow.h" +#include "qwidget.h" +#include "QtGui/qplatformnativeinterface_qpa.h" #include "QtCore/qmutex.h" #include "QtCore/qtranslator.h" #include "QtCore/qbasictimer.h" @@ -512,6 +515,13 @@ public: #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA) void sendSyntheticEnterLeave(QWidget *widget); #endif +#ifdef Q_OS_WIN + static HWND getHWNDForWidget(QWidget *widget) + { + QWindow *window = qobject_cast(widget); + return static_cast ("handle", QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", window)); + } +#endif #ifndef QT_NO_GESTURES QGestureManager *gestureManager; diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index dcda20138d..1b37ddf2e0 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -434,6 +434,18 @@ void qt_init(QApplicationPrivate *, int type) #endif } +#ifdef Q_OS_WIN +static HDC displayDC = 0; // display device context + +Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC +{ + Q_ASSERT(qApp && qApp->thread() == QThread::currentThread()); + if (!displayDC) + displayDC = GetDC(0); + return displayDC; +} +#endif + void qt_cleanup() { QPixmapCache::clear(); @@ -442,9 +454,14 @@ void qt_cleanup() QApplicationPrivate::inputContext = 0; QApplicationPrivate::active_window = 0; //### this should not be necessary +#ifdef Q_OS_WIN + if (displayDC) { + ReleaseDC(0, displayDC); + displayDC = 0; + } +#endif } - #ifdef QT3_SUPPORT void QApplication::setMainWidget(QWidget *mainWidget) { diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index da484bafe1..55e83f79fa 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -43,6 +43,8 @@ #include "qwindowsvistastyle_p.h" #include #include +#include +#include #if !defined(QT_NO_STYLE_WINDOWSVISTA) || defined(QT_PLUGIN) @@ -2606,7 +2608,8 @@ QWidget *QWindowsVistaStylePrivate::treeViewHelper() { if (!m_treeViewHelper) { m_treeViewHelper = new QWidget(0); - pSetWindowTheme(m_treeViewHelper->winId(), L"explorer", NULL); + HWND handle = QApplicationPrivate::getHWNDForWidget(m_treeViewHelper); + pSetWindowTheme(handle, L"explorer", NULL); } return m_treeViewHelper; } diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index 83d47db20f..36e0852462 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -295,9 +296,10 @@ void QWindowsXPStylePrivate::cleanupHandleMap() */ HWND QWindowsXPStylePrivate::winId(const QWidget *widget) { - if (widget && widget->internalWinId()) - return widget->internalWinId(); - + if (widget && widget->internalWinId()) { + QWidget *w = const_cast(widget); + return QApplicationPrivate::getHWNDForWidget(w); + } if (!limboWidget) { limboWidget = new QWidget(0); limboWidget->createWinId(); @@ -307,7 +309,7 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget) QWidgetPrivate::allWidgets->remove(limboWidget); } - return limboWidget->winId(); + return QApplicationPrivate::getHWNDForWidget(limboWidget); } /*! \internal @@ -466,8 +468,31 @@ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData) QRegion region; - if (success) - region = qt_region_from_HRGN(dest); + if (success) { + int numBytes = GetRegionData(dest, 0, 0); + if (numBytes == 0) + return QRegion(); + + char *buf = new char[numBytes]; + if (buf == 0) + return QRegion(); + + RGNDATA *rd = reinterpret_cast(buf); + if (GetRegionData(dest, numBytes, rd) == 0) { + delete [] buf; + return QRegion(); + } + + RECT *r = reinterpret_cast(rd->Buffer); + for (uint i = 0; i < rd->rdh.nCount; ++i) { + QRect rect; + rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1); + ++r; + region |= rect; + } + + delete [] buf; + } DeleteObject(hRgn); DeleteObject(dest);