summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowstheme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows/qwindowstheme.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp183
1 files changed, 113 insertions, 70 deletions
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index cc367ff801..c64955be80 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** 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.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.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.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -78,11 +84,6 @@
QT_BEGIN_NAMESPACE
-static inline COLORREF qColorToCOLORREF(const QColor &color)
-{
- return RGB(color.red(), color.green(), color.blue());
-}
-
static inline QColor COLORREFToQColor(COLORREF cr)
{
return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr));
@@ -99,30 +100,6 @@ static inline QTextStream& operator<<(QTextStream &str, const QColor &c)
return str;
}
-static inline void paletteRoleToString(const QPalette &palette,
- const QPalette::ColorRole role,
- QTextStream &str)
-{
- str << "Role: ";
- str.setFieldWidth(2);
- str.setPadChar(QLatin1Char('0'));
- str << role;
- str.setFieldWidth(0);
- str << " Active: " << palette.color(QPalette::Active, role)
- << " Disabled: " << palette.color(QPalette::Disabled, role)
- << " Inactive: " << palette.color(QPalette::Inactive, role)
- << '\n';
-}
-
-static inline QString paletteToString(const QPalette &palette)
-{
- QString result;
- QTextStream str(&result);
- for (int r = 0; r < QPalette::NColorRoles; ++r)
- paletteRoleToString(palette, static_cast<QPalette::ColorRole>(r), str);
- return result;
-}
-
static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue)
{
BOOL result;
@@ -151,6 +128,41 @@ static inline QColor getSysColor(int index)
return COLORREFToQColor(GetSysColor(index));
}
+#ifndef QT_NO_WINCE_SHELLSDK
+// QTBUG-48823/Windows 10: SHGetFileInfo() (as called by item views on file system
+// models has been observed to trigger a WM_PAINT on the mainwindow. Suppress the
+// behavior by running it in a thread.
+class ShGetFileInfoFunction
+{
+public:
+ explicit ShGetFileInfoFunction(const wchar_t *fn, DWORD a, SHFILEINFO *i, UINT f, bool *r) :
+ m_fileName(fn), m_attributes(a), m_flags(f), m_info(i), m_result(r) {}
+
+ void operator()() const { *m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags); }
+
+private:
+ const wchar_t *m_fileName;
+ const DWORD m_attributes;
+ const UINT m_flags;
+ SHFILEINFO *const m_info;
+ bool *m_result;
+};
+
+static bool shGetFileInfoBackground(QWindowsThreadPoolRunner &r,
+ const wchar_t *fileName, DWORD attributes,
+ SHFILEINFO *info, UINT flags,
+ unsigned long timeOutMSecs = 5000)
+{
+ bool result = false;
+ if (!r.run(ShGetFileInfoFunction(fileName, attributes, info, flags, &result), timeOutMSecs)) {
+ qWarning().noquote() << "ShGetFileInfoBackground() timed out for "
+ << QString::fromWCharArray(fileName);
+ return false;
+ }
+ return result;
+}
+#endif // !QT_NO_WINCE_SHELLSDK
+
// from QStyle::standardPalette
static inline QPalette standardPalette()
{
@@ -485,7 +497,9 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
HMODULE hmod = QSystemLibrary::load(L"shell32");
#endif
if (hmod) {
- HICON iconHandle = (HICON)LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, size.width(), size.height(), 0);
+ HICON iconHandle =
+ static_cast<HICON>(LoadImage(hmod, MAKEINTRESOURCE(resourceId),
+ IMAGE_ICON, int(size.width()), int(size.height()), 0));
if (iconHandle) {
QPixmap iconpixmap = qt_pixmapFromWinHICON(iconHandle);
DestroyIcon(iconHandle);
@@ -501,28 +515,43 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
const int scaleFactor = primaryScreen ? qRound(QHighDpiScaling::factor(primaryScreen)) : 1;
const QSizeF pixmapSize = size * scaleFactor;
int resourceId = -1;
+ int stockId = SIID_INVALID;
+ UINT stockFlags = 0;
LPCTSTR iconName = 0;
switch (sp) {
case DriveCDIcon:
+ stockId = SIID_DRIVECD;
+ resourceId = 12;
+ break;
case DriveDVDIcon:
+ stockId = SIID_DRIVEDVD;
resourceId = 12;
break;
case DriveNetIcon:
+ stockId = SIID_DRIVENET;
resourceId = 10;
break;
case DriveHDIcon:
+ stockId = SIID_DRIVEFIXED;
resourceId = 9;
break;
case DriveFDIcon:
+ stockId = SIID_DRIVE35;
resourceId = 7;
break;
- case FileIcon:
case FileLinkIcon:
+ stockFlags = SHGSI_LINKOVERLAY;
+ // Fall through
+ case FileIcon:
+ stockId = SIID_DOCNOASSOC;
resourceId = 1;
break;
- case DirIcon:
case DirLinkIcon:
+ stockFlags = SHGSI_LINKOVERLAY;
+ // Fall through
case DirClosedIcon:
+ case DirIcon:
+ stockId = SIID_FOLDER;
resourceId = 4;
break;
case DesktopIcon:
@@ -531,54 +560,68 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
case ComputerIcon:
resourceId = 16;
break;
- case DirOpenIcon:
case DirLinkOpenIcon:
+ stockFlags = SHGSI_LINKOVERLAY;
+ // Fall through
+ case DirOpenIcon:
+ stockId = SIID_FOLDEROPEN;
resourceId = 5;
break;
case FileDialogNewFolder:
+ stockId = SIID_FOLDER;
resourceId = 319;
break;
case DirHomeIcon:
resourceId = 235;
break;
case TrashIcon:
+ stockId = SIID_RECYCLER;
resourceId = 191;
break;
#ifndef Q_OS_WINCE
case MessageBoxInformation:
+ stockId = SIID_INFO;
iconName = IDI_INFORMATION;
break;
case MessageBoxWarning:
+ stockId = SIID_WARNING;
iconName = IDI_WARNING;
break;
case MessageBoxCritical:
+ stockId = SIID_ERROR;
iconName = IDI_ERROR;
break;
case MessageBoxQuestion:
+ stockId = SIID_HELP;
iconName = IDI_QUESTION;
break;
case VistaShield:
+ stockId = SIID_SHIELD;
+ break;
+#endif
+ default:
+ break;
+ }
+
+#ifndef Q_OS_WINCE
+ if (stockId != SIID_INVALID) {
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
- && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) {
- if (!QWindowsContext::shell32dll.sHGetStockIconInfo)
- return QPixmap();
+ && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
+ && QWindowsContext::shell32dll.sHGetStockIconInfo) {
QPixmap pixmap;
SHSTOCKICONINFO iconInfo;
memset(&iconInfo, 0, sizeof(iconInfo));
iconInfo.cbSize = sizeof(iconInfo);
- const int iconSize = pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
- if (QWindowsContext::shell32dll.sHGetStockIconInfo(SIID_SHIELD, SHGFI_ICON | iconSize, &iconInfo) == S_OK) {
+ stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON);
+ if (QWindowsContext::shell32dll.sHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) {
pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
pixmap.setDevicePixelRatio(scaleFactor);
DestroyIcon(iconInfo.hIcon);
return pixmap;
}
}
- break;
-#endif
- default:
- break;
}
+#endif
if (resourceId != -1) {
QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);
@@ -586,7 +629,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) {
QPainter painter(&pixmap);
QPixmap link = loadIconFromShell32(30, pixmapSize);
- painter.drawPixmap(0, 0, pixmapSize.width(), pixmapSize.height(), link);
+ painter.drawPixmap(0, 0, int(pixmapSize.width()), int(pixmapSize.height()), link);
}
pixmap.setDevicePixelRatio(scaleFactor);
return pixmap;
@@ -661,7 +704,8 @@ static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info)
return result;
IImageList *imageList = 0;
- HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList, (void **)&imageList);
+ HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList,
+ reinterpret_cast<void **>(&imageList));
if (hr != S_OK)
return result;
HICON hIcon;
@@ -693,7 +737,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
QPixmap pixmap;
const QString filePath = QDir::toNativeSeparators(fileInfo.filePath());
- const int width = size.width();
+ const int width = int(size.width());
const int iconSize = width > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
const int requestedImageListSize =
#ifdef USE_IIMAGELIST
@@ -716,23 +760,22 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
}
SHFILEINFO info;
- unsigned int flags =
+ const unsigned int flags =
#ifndef Q_OS_WINCE
SHGFI_ICON|iconSize|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX;
#else
iconSize|SHGFI_SYSICONINDEX;
#endif // Q_OS_WINCE
- unsigned long val = 0;
+
+
#if !defined(QT_NO_WINCE_SHELLSDK)
- if (cacheableDirIcon && useDefaultFolderIcon) {
- flags |= SHGFI_USEFILEATTRIBUTES;
- val = SHGetFileInfo(L"dummy",
- FILE_ATTRIBUTE_DIRECTORY,
- &info, sizeof(SHFILEINFO), flags);
- } else {
- val = SHGetFileInfo(reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
- &info, sizeof(SHFILEINFO), flags);
- }
+ const bool val = cacheableDirIcon && useDefaultFolderIcon
+ ? shGetFileInfoBackground(m_threadPoolRunner, L"dummy", FILE_ATTRIBUTE_DIRECTORY,
+ &info, flags | SHGFI_USEFILEATTRIBUTES)
+ : shGetFileInfoBackground(m_threadPoolRunner, reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
+ &info, flags);
+#else
+ const bool val = false;
#endif // !QT_NO_WINCE_SHELLSDK
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases