Windows QPA: Increase API level to 0x600 (Windows Vista).

- Directly link against dwmapi which should be present on
  Windows Vista and remove duplicated header constants.
- Remove struct QWindowsShell32DL since all required functions
  are present on Windows Vista.
- Remove functions that are no longer needed from QWindowsUser32DLL
  with exception of the clipboard functions which are not present
  in the MinGW stub libraries until v5.

Task-number: QTBUG-51673
Change-Id: Ia4a8a3f1db0f0d02322317d547e61ae39f9008b5
Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
This commit is contained in:
Friedemann Kleint 2016-03-09 09:14:23 +01:00
parent 2cba33901b
commit 5cbc460990
8 changed files with 62 additions and 199 deletions

View File

@ -100,19 +100,15 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
POINT ptDst = {r.x(), r.y()}; POINT ptDst = {r.x(), r.y()};
POINT ptSrc = {0, 0}; POINT ptSrc = {0, 0};
BLENDFUNCTION blend = {AC_SRC_OVER, 0, BYTE(qRound(255.0 * rw->opacity())), AC_SRC_ALPHA}; BLENDFUNCTION blend = {AC_SRC_OVER, 0, BYTE(qRound(255.0 * rw->opacity())), AC_SRC_ALPHA};
if (QWindowsContext::user32dll.updateLayeredWindowIndirect) { RECT dirty = {dirtyRect.x(), dirtyRect.y(),
RECT dirty = {dirtyRect.x(), dirtyRect.y(), dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()};
dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()}; UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA, &dirty};
UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA, &dirty}; const BOOL result = UpdateLayeredWindowIndirect(rw->handle(), &info);
const BOOL result = QWindowsContext::user32dll.updateLayeredWindowIndirect(rw->handle(), &info); if (!result)
if (!result) qErrnoWarning("UpdateLayeredWindowIndirect failed for ptDst=(%d, %d),"
qErrnoWarning("UpdateLayeredWindowIndirect failed for ptDst=(%d, %d)," " size=(%dx%d), dirty=(%dx%d %d, %d)", r.x(), r.y(),
" size=(%dx%d), dirty=(%dx%d %d, %d)", r.x(), r.y(), r.width(), r.height(), dirtyRect.width(), dirtyRect.height(),
r.width(), r.height(), dirtyRect.width(), dirtyRect.height(), dirtyRect.x(), dirtyRect.y());
dirtyRect.x(), dirtyRect.y());
} else {
QWindowsContext::user32dll.updateLayeredWindow(rw->handle(), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA);
}
} else { } else {
const HDC dc = rw->getDC(); const HDC dc = rw->getDC();
if (!dc) { if (!dc) {

View File

@ -237,8 +237,7 @@ void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, L
return; return;
// In rare cases, a clipboard viewer can hang (application crashed, // In rare cases, a clipboard viewer can hang (application crashed,
// suspended by a shell prompt 'Select' or debugger). // suspended by a shell prompt 'Select' or debugger).
if (QWindowsContext::user32dll.isHungAppWindow if (IsHungAppWindow(m_nextClipboardViewer)) {
&& QWindowsContext::user32dll.isHungAppWindow(m_nextClipboardViewer)) {
qWarning("Cowardly refusing to send clipboard message to hung application..."); qWarning("Cowardly refusing to send clipboard message to hung application...");
return; return;
} }

View File

@ -97,35 +97,26 @@ int QWindowsContext::verbose = 0;
# define LANG_SYRIAC 0x5a # define LANG_SYRIAC 0x5a
#endif #endif
static inline bool useRTL_Extensions(QSysInfo::WinVersion ver) static inline bool useRTL_Extensions()
{ {
if ((ver & QSysInfo::WV_NT_based) && (ver >= QSysInfo::WV_VISTA)) { // Since the IsValidLanguageGroup/IsValidLocale functions always return true on
// Since the IsValidLanguageGroup/IsValidLocale functions always return true on // Vista, check the Keyboard Layouts for enabling RTL.
// Vista, check the Keyboard Layouts for enabling RTL. if (const int nLayouts = GetKeyboardLayoutList(0, 0)) {
if (const int nLayouts = GetKeyboardLayoutList(0, 0)) { QScopedArrayPointer<HKL> lpList(new HKL[nLayouts]);
QScopedArrayPointer<HKL> lpList(new HKL[nLayouts]); GetKeyboardLayoutList(nLayouts, lpList.data());
GetKeyboardLayoutList(nLayouts, lpList.data()); for (int i = 0; i < nLayouts; ++i) {
for (int i = 0; i < nLayouts; ++i) { switch (PRIMARYLANGID((quintptr)lpList[i])) {
switch (PRIMARYLANGID((quintptr)lpList[i])) { case LANG_ARABIC:
case LANG_ARABIC: case LANG_HEBREW:
case LANG_HEBREW: case LANG_FARSI:
case LANG_FARSI: case LANG_SYRIAC:
case LANG_SYRIAC: return true;
return true; default:
default: break;
break;
}
} }
} }
return false; }
} // NT/Vista return false;
// Pre-NT: figure out whether a RTL language is installed
return IsValidLanguageGroup(LGRPID_ARABIC, LGRPID_INSTALLED)
|| IsValidLanguageGroup(LGRPID_HEBREW, LGRPID_INSTALLED)
|| IsValidLocale(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
|| IsValidLocale(MAKELCID(MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
|| IsValidLocale(MAKELCID(MAKELANGID(LANG_SYRIAC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
|| IsValidLocale(MAKELCID(MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED);
} }
#if !defined(QT_NO_SESSIONMANAGER) #if !defined(QT_NO_SESSIONMANAGER)
@ -152,9 +143,7 @@ static inline QWindowsSessionManager *platformSessionManager() {
\ingroup qt-lighthouse-win \ingroup qt-lighthouse-win
*/ */
QWindowsUser32DLL::QWindowsUser32DLL() : QWindowsUser32DLL::QWindowsUser32DLL() :
setLayeredWindowAttributes(0), updateLayeredWindow(0), isTouchWindow(0),
updateLayeredWindowIndirect(0),
isHungAppWindow(0), isTouchWindow(0),
registerTouchWindow(0), unregisterTouchWindow(0), registerTouchWindow(0), unregisterTouchWindow(0),
getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0), getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0),
addClipboardFormatListener(0), removeClipboardFormatListener(0), addClipboardFormatListener(0), removeClipboardFormatListener(0),
@ -165,20 +154,11 @@ QWindowsUser32DLL::QWindowsUser32DLL() :
void QWindowsUser32DLL::init() void QWindowsUser32DLL::init()
{ {
QSystemLibrary library(QStringLiteral("user32")); QSystemLibrary library(QStringLiteral("user32"));
// MinGW (g++ 3.4.5) accepts only C casts.
setLayeredWindowAttributes = (SetLayeredWindowAttributes)(library.resolve("SetLayeredWindowAttributes"));
updateLayeredWindow = (UpdateLayeredWindow)(library.resolve("UpdateLayeredWindow"));
if (Q_UNLIKELY(!setLayeredWindowAttributes || !updateLayeredWindow))
qFatal("This version of Windows is not supported (User32.dll is missing the symbols 'SetLayeredWindowAttributes', 'UpdateLayeredWindow').");
updateLayeredWindowIndirect = (UpdateLayeredWindowIndirect)(library.resolve("UpdateLayeredWindowIndirect"));
isHungAppWindow = (IsHungAppWindow)library.resolve("IsHungAppWindow");
setProcessDPIAware = (SetProcessDPIAware)library.resolve("SetProcessDPIAware"); setProcessDPIAware = (SetProcessDPIAware)library.resolve("SetProcessDPIAware");
if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) { addClipboardFormatListener = (AddClipboardFormatListener)library.resolve("AddClipboardFormatListener");
addClipboardFormatListener = (AddClipboardFormatListener)library.resolve("AddClipboardFormatListener"); removeClipboardFormatListener = (RemoveClipboardFormatListener)library.resolve("RemoveClipboardFormatListener");
removeClipboardFormatListener = (RemoveClipboardFormatListener)library.resolve("RemoveClipboardFormatListener");
}
getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences"); getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences");
setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences"); setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences");
} }
@ -196,38 +176,6 @@ bool QWindowsUser32DLL::initTouch()
return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle;
} }
/*!
\class QWindowsShell32DLL
\brief Struct that contains dynamically resolved symbols of Shell32.dll.
The stub libraries shipped with the MinGW compiler miss some of the
functions. They need to be retrieved dynamically.
\sa QWindowsUser32DLL
\internal
\ingroup qt-lighthouse-win
*/
QWindowsShell32DLL::QWindowsShell32DLL()
: sHCreateItemFromParsingName(0)
, sHGetKnownFolderIDList(0)
, sHGetStockIconInfo(0)
, sHGetImageList(0)
, sHCreateItemFromIDList(0)
{
}
void QWindowsShell32DLL::init()
{
QSystemLibrary library(QStringLiteral("shell32"));
sHCreateItemFromParsingName = (SHCreateItemFromParsingName)(library.resolve("SHCreateItemFromParsingName"));
sHGetKnownFolderIDList = (SHGetKnownFolderIDList)(library.resolve("SHGetKnownFolderIDList"));
sHGetStockIconInfo = (SHGetStockIconInfo)library.resolve("SHGetStockIconInfo");
sHGetImageList = (SHGetImageList)library.resolve("SHGetImageList");
sHCreateItemFromIDList = (SHCreateItemFromIDList)library.resolve("SHCreateItemFromIDList");
}
QWindowsShcoreDLL::QWindowsShcoreDLL() QWindowsShcoreDLL::QWindowsShcoreDLL()
: getProcessDpiAwareness(0) : getProcessDpiAwareness(0)
, setProcessDpiAwareness(0) , setProcessDpiAwareness(0)
@ -246,7 +194,6 @@ void QWindowsShcoreDLL::init()
} }
QWindowsUser32DLL QWindowsContext::user32dll; QWindowsUser32DLL QWindowsContext::user32dll;
QWindowsShell32DLL QWindowsContext::shell32dll;
QWindowsShcoreDLL QWindowsContext::shcoredll; QWindowsShcoreDLL QWindowsContext::shcoredll;
QWindowsContext *QWindowsContext::m_instance = 0; QWindowsContext *QWindowsContext::m_instance = 0;
@ -292,16 +239,14 @@ QWindowsContextPrivate::QWindowsContextPrivate()
, m_eventType(QByteArrayLiteral("windows_generic_MSG")) , m_eventType(QByteArrayLiteral("windows_generic_MSG"))
, m_lastActiveWindow(0), m_asyncExpose(0) , m_lastActiveWindow(0), m_asyncExpose(0)
{ {
const QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
QWindowsContext::user32dll.init(); QWindowsContext::user32dll.init();
QWindowsContext::shell32dll.init();
QWindowsContext::shcoredll.init(); QWindowsContext::shcoredll.init();
if (m_mouseHandler.touchDevice() && QWindowsContext::user32dll.initTouch()) if (m_mouseHandler.touchDevice() && QWindowsContext::user32dll.initTouch())
m_systemInfo |= QWindowsContext::SI_SupportsTouch; m_systemInfo |= QWindowsContext::SI_SupportsTouch;
m_displayContext = GetDC(0); m_displayContext = GetDC(0);
m_defaultDPI = GetDeviceCaps(m_displayContext, LOGPIXELSY); m_defaultDPI = GetDeviceCaps(m_displayContext, LOGPIXELSY);
if (useRTL_Extensions(ver)) { if (useRTL_Extensions()) {
m_systemInfo |= QWindowsContext::SI_RTL_Extensions; m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
m_keyMapper.setUseRTLExtensions(true); m_keyMapper.setUseRTLExtensions(true);
} }

View File

@ -85,31 +85,17 @@ struct QWindowsUser32DLL
inline void init(); inline void init();
inline bool initTouch(); inline bool initTouch();
typedef BOOL (WINAPI *IsTouchWindow)(HWND, PULONG); typedef BOOL (WINAPI *IsTouchWindow)(HWND, PULONG); // Windows 7
typedef BOOL (WINAPI *RegisterTouchWindow)(HWND, ULONG); typedef BOOL (WINAPI *RegisterTouchWindow)(HWND, ULONG);
typedef BOOL (WINAPI *UnregisterTouchWindow)(HWND); typedef BOOL (WINAPI *UnregisterTouchWindow)(HWND);
typedef BOOL (WINAPI *GetTouchInputInfo)(HANDLE, UINT, PVOID, int); typedef BOOL (WINAPI *GetTouchInputInfo)(HANDLE, UINT, PVOID, int);
typedef BOOL (WINAPI *CloseTouchInputHandle)(HANDLE); typedef BOOL (WINAPI *CloseTouchInputHandle)(HANDLE);
typedef BOOL (WINAPI *SetLayeredWindowAttributes)(HWND, COLORREF, BYTE, DWORD);
typedef BOOL (WINAPI *UpdateLayeredWindow)(HWND, HDC , const POINT *,
const SIZE *, HDC, const POINT *, COLORREF,
const BLENDFUNCTION *, DWORD);
typedef BOOL (WINAPI *UpdateLayeredWindowIndirect)(HWND, const UPDATELAYEREDWINDOWINFO *);
typedef BOOL (WINAPI *IsHungAppWindow)(HWND);
typedef BOOL (WINAPI *SetProcessDPIAware)(); typedef BOOL (WINAPI *SetProcessDPIAware)();
typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND); typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND); typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *); typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *);
typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD); typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD);
// Functions missing in Q_CC_GNU stub libraries.
SetLayeredWindowAttributes setLayeredWindowAttributes;
UpdateLayeredWindow updateLayeredWindow;
// Functions missing in older versions of Windows
UpdateLayeredWindowIndirect updateLayeredWindowIndirect;
IsHungAppWindow isHungAppWindow;
// Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC). // Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC).
IsTouchWindow isTouchWindow; IsTouchWindow isTouchWindow;
RegisterTouchWindow registerTouchWindow; RegisterTouchWindow registerTouchWindow;
@ -120,7 +106,8 @@ struct QWindowsUser32DLL
// Windows Vista onwards // Windows Vista onwards
SetProcessDPIAware setProcessDPIAware; SetProcessDPIAware setProcessDPIAware;
// Clipboard listeners, Windows Vista onwards // Clipboard listeners are present on Windows Vista onwards
// but missing in MinGW 4.9 stub libs. Can be removed in MinGW 5.
AddClipboardFormatListener addClipboardFormatListener; AddClipboardFormatListener addClipboardFormatListener;
RemoveClipboardFormatListener removeClipboardFormatListener; RemoveClipboardFormatListener removeClipboardFormatListener;
@ -129,24 +116,6 @@ struct QWindowsUser32DLL
SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences; SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences;
}; };
struct QWindowsShell32DLL
{
QWindowsShell32DLL();
inline void init();
typedef HRESULT (WINAPI *SHCreateItemFromParsingName)(PCWSTR, IBindCtx *, const GUID&, void **);
typedef HRESULT (WINAPI *SHGetKnownFolderIDList)(const GUID &, DWORD, HANDLE, PIDLIST_ABSOLUTE *);
typedef HRESULT (WINAPI *SHGetStockIconInfo)(int , int , _SHSTOCKICONINFO *);
typedef HRESULT (WINAPI *SHGetImageList)(int, REFIID , void **);
typedef HRESULT (WINAPI *SHCreateItemFromIDList)(PCIDLIST_ABSOLUTE, REFIID, void **);
SHCreateItemFromParsingName sHCreateItemFromParsingName;
SHGetKnownFolderIDList sHGetKnownFolderIDList;
SHGetStockIconInfo sHGetStockIconInfo;
SHGetImageList sHGetImageList;
SHCreateItemFromIDList sHCreateItemFromIDList;
};
// Shell scaling library (Windows 8.1 onwards) // Shell scaling library (Windows 8.1 onwards)
struct QWindowsShcoreDLL { struct QWindowsShcoreDLL {
QWindowsShcoreDLL(); QWindowsShcoreDLL();
@ -235,7 +204,6 @@ public:
QWindowsTabletSupport *tabletSupport() const; QWindowsTabletSupport *tabletSupport() const;
static QWindowsUser32DLL user32dll; static QWindowsUser32DLL user32dll;
static QWindowsShell32DLL shell32dll;
static QWindowsShcoreDLL shcoredll; static QWindowsShcoreDLL shcoredll;
static QByteArray comErrorString(HRESULT hr); static QByteArray comErrorString(HRESULT hr);

View File

@ -988,22 +988,18 @@ void QWindowsNativeFileDialogBase::setWindowTitle(const QString &title)
IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url) IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url)
{ {
if (url.isLocalFile()) { if (url.isLocalFile()) {
if (!QWindowsContext::shell32dll.sHCreateItemFromParsingName)
return Q_NULLPTR;
IShellItem *result = Q_NULLPTR; IShellItem *result = Q_NULLPTR;
const QString native = QDir::toNativeSeparators(url.toLocalFile()); const QString native = QDir::toNativeSeparators(url.toLocalFile());
const HRESULT hr = const HRESULT hr =
QWindowsContext::shell32dll.sHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()), SHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
NULL, IID_IShellItem, NULL, IID_IShellItem,
reinterpret_cast<void **>(&result)); reinterpret_cast<void **>(&result));
if (FAILED(hr)) { if (FAILED(hr)) {
qErrnoWarning("%s: SHCreateItemFromParsingName(%s)) failed", __FUNCTION__, qPrintable(url.toString())); qErrnoWarning("%s: SHCreateItemFromParsingName(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
return Q_NULLPTR; return Q_NULLPTR;
} }
return result; return result;
} else if (url.scheme() == QLatin1String("clsid")) { } else if (url.scheme() == QLatin1String("clsid")) {
if (!QWindowsContext::shell32dll.sHGetKnownFolderIDList || !QWindowsContext::shell32dll.sHCreateItemFromIDList)
return Q_NULLPTR;
// Support for virtual folders via GUID // Support for virtual folders via GUID
// (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx) // (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx)
// specified as "clsid:<GUID>" (without '{', '}'). // specified as "clsid:<GUID>" (without '{', '}').
@ -1014,12 +1010,12 @@ IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url)
return Q_NULLPTR; return Q_NULLPTR;
} }
PIDLIST_ABSOLUTE idList; PIDLIST_ABSOLUTE idList;
HRESULT hr = QWindowsContext::shell32dll.sHGetKnownFolderIDList(uuid, 0, 0, &idList); HRESULT hr = SHGetKnownFolderIDList(uuid, 0, 0, &idList);
if (FAILED(hr)) { if (FAILED(hr)) {
qErrnoWarning("%s: SHGetKnownFolderIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString())); qErrnoWarning("%s: SHGetKnownFolderIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
return Q_NULLPTR; return Q_NULLPTR;
} }
hr = QWindowsContext::shell32dll.sHCreateItemFromIDList(idList, IID_IShellItem, reinterpret_cast<void **>(&result)); hr = SHCreateItemFromIDList(idList, IID_IShellItem, reinterpret_cast<void **>(&result));
CoTaskMemFree(idList); CoTaskMemFree(idList);
if (FAILED(hr)) { if (FAILED(hr)) {
qErrnoWarning("%s: SHCreateItemFromIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString())); qErrnoWarning("%s: SHCreateItemFromIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString()));

View File

@ -490,7 +490,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
const int scaleFactor = primaryScreen ? qRound(QHighDpiScaling::factor(primaryScreen)) : 1; const int scaleFactor = primaryScreen ? qRound(QHighDpiScaling::factor(primaryScreen)) : 1;
const QSizeF pixmapSize = size * scaleFactor; const QSizeF pixmapSize = size * scaleFactor;
int resourceId = -1; int resourceId = -1;
int stockId = SIID_INVALID; SHSTOCKICONID stockId = SIID_INVALID;
UINT stockFlags = 0; UINT stockFlags = 0;
LPCTSTR iconName = 0; LPCTSTR iconName = 0;
switch (sp) { switch (sp) {
@ -577,20 +577,16 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
} }
if (stockId != SIID_INVALID) { if (stockId != SIID_INVALID) {
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA QPixmap pixmap;
&& (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) SHSTOCKICONINFO iconInfo;
&& QWindowsContext::shell32dll.sHGetStockIconInfo) { memset(&iconInfo, 0, sizeof(iconInfo));
QPixmap pixmap; iconInfo.cbSize = sizeof(iconInfo);
SHSTOCKICONINFO iconInfo; stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON);
memset(&iconInfo, 0, sizeof(iconInfo)); if (SHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) {
iconInfo.cbSize = sizeof(iconInfo); pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON); pixmap.setDevicePixelRatio(scaleFactor);
if (QWindowsContext::shell32dll.sHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) { DestroyIcon(iconInfo.hIcon);
pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon); return pixmap;
pixmap.setDevicePixelRatio(scaleFactor);
DestroyIcon(iconInfo.hIcon);
return pixmap;
}
} }
} }
@ -669,14 +665,8 @@ static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info)
// For MinGW: // For MinGW:
static const IID iID_IImageList = {0x46eb5926, 0x582e, 0x4017, {0x9f, 0xdf, 0xe8, 0x99, 0x8d, 0xaa, 0x9, 0x50}}; static const IID iID_IImageList = {0x46eb5926, 0x582e, 0x4017, {0x9f, 0xdf, 0xe8, 0x99, 0x8d, 0xaa, 0x9, 0x50}};
if (!QWindowsContext::shell32dll.sHGetImageList)
return result;
if (iImageList == sHIL_JUMBO && QSysInfo::WindowsVersion < QSysInfo::WV_VISTA)
return result;
IImageList *imageList = 0; IImageList *imageList = 0;
HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList, HRESULT hr = SHGetImageList(iImageList, iID_IImageList, reinterpret_cast<void **>(&imageList));
reinterpret_cast<void **>(&imageList));
if (hr != S_OK) if (hr != S_OK)
return result; return result;
HICON hIcon; HICON hIcon;

View File

@ -62,6 +62,8 @@
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <dwmapi.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
enum { enum {
@ -258,55 +260,22 @@ static inline bool windowIsOpenGL(const QWindow *w)
static bool applyBlurBehindWindow(HWND hwnd) static bool applyBlurBehindWindow(HWND hwnd)
{ {
enum { dwmBbEnable = 0x1, dwmBbBlurRegion = 0x2 };
struct DwmBlurBehind {
DWORD dwFlags;
BOOL fEnable;
HRGN hRgnBlur;
BOOL fTransitionOnMaximized;
};
typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND, const DwmBlurBehind*);
typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL *);
// DWM API is available only from Windows Vista
if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA)
return false;
static bool functionPointersResolved = false;
static PtrDwmEnableBlurBehindWindow dwmBlurBehind = 0;
static PtrDwmIsCompositionEnabled dwmIsCompositionEnabled = 0;
if (Q_UNLIKELY(!functionPointersResolved)) {
QSystemLibrary library(QStringLiteral("dwmapi"));
if (library.load()) {
dwmBlurBehind = (PtrDwmEnableBlurBehindWindow)(library.resolve("DwmEnableBlurBehindWindow"));
dwmIsCompositionEnabled = (PtrDwmIsCompositionEnabled)(library.resolve("DwmIsCompositionEnabled"));
}
functionPointersResolved = true;
}
if (Q_UNLIKELY(!dwmBlurBehind || !dwmIsCompositionEnabled))
return false;
BOOL compositionEnabled; BOOL compositionEnabled;
if (dwmIsCompositionEnabled(&compositionEnabled) != S_OK) if (DwmIsCompositionEnabled(&compositionEnabled) != S_OK)
return false; return false;
DwmBlurBehind blurBehind = {0, 0, 0, 0}; DWM_BLURBEHIND blurBehind = {0, 0, 0, 0};
if (compositionEnabled) { if (compositionEnabled) {
blurBehind.dwFlags = dwmBbEnable | dwmBbBlurRegion; blurBehind.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
blurBehind.fEnable = TRUE; blurBehind.fEnable = TRUE;
blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1); blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
} else { } else {
blurBehind.dwFlags = dwmBbEnable; blurBehind.dwFlags = DWM_BB_ENABLE;
blurBehind.fEnable = FALSE; blurBehind.fEnable = FALSE;
} }
const bool result = dwmBlurBehind(hwnd, &blurBehind) == S_OK; const bool result = DwmEnableBlurBehindWindow(hwnd, &blurBehind) == S_OK;
if (blurBehind.hRgnBlur) if (blurBehind.hRgnBlur)
DeleteObject(blurBehind.hRgnBlur); DeleteObject(blurBehind.hRgnBlur);
@ -351,9 +320,9 @@ static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bo
if (hasAlpha && !openGL && (flags & Qt::FramelessWindowHint)) { if (hasAlpha && !openGL && (flags & Qt::FramelessWindowHint)) {
// Non-GL windows with alpha: Use blend function to update. // Non-GL windows with alpha: Use blend function to update.
BLENDFUNCTION blend = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA}; BLENDFUNCTION blend = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
QWindowsContext::user32dll.updateLayeredWindow(hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA); UpdateLayeredWindow(hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA);
} else { } else {
QWindowsContext::user32dll.setLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA); SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA);
} }
} else if (IsWindowVisible(hwnd)) { // Repaint when switching from layered. } else if (IsWindowVisible(hwnd)) { // Repaint when switching from layered.
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);

View File

@ -4,7 +4,7 @@ QT *= core-private
QT *= gui-private QT *= gui-private
QT *= platformsupport-private QT *= platformsupport-private
LIBS += -lgdi32 LIBS += -lgdi32 -ldwmapi
include(windows.pri) include(windows.pri)