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:
parent
2cba33901b
commit
5cbc460990
@ -100,19 +100,15 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion,
|
||||
POINT ptDst = {r.x(), r.y()};
|
||||
POINT ptSrc = {0, 0};
|
||||
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(),
|
||||
dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()};
|
||||
UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA, &dirty};
|
||||
const BOOL result = QWindowsContext::user32dll.updateLayeredWindowIndirect(rw->handle(), &info);
|
||||
if (!result)
|
||||
qErrnoWarning("UpdateLayeredWindowIndirect failed for ptDst=(%d, %d),"
|
||||
" size=(%dx%d), dirty=(%dx%d %d, %d)", r.x(), r.y(),
|
||||
r.width(), r.height(), dirtyRect.width(), dirtyRect.height(),
|
||||
dirtyRect.x(), dirtyRect.y());
|
||||
} else {
|
||||
QWindowsContext::user32dll.updateLayeredWindow(rw->handle(), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA);
|
||||
}
|
||||
RECT dirty = {dirtyRect.x(), dirtyRect.y(),
|
||||
dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()};
|
||||
UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA, &dirty};
|
||||
const BOOL result = UpdateLayeredWindowIndirect(rw->handle(), &info);
|
||||
if (!result)
|
||||
qErrnoWarning("UpdateLayeredWindowIndirect failed for ptDst=(%d, %d),"
|
||||
" size=(%dx%d), dirty=(%dx%d %d, %d)", r.x(), r.y(),
|
||||
r.width(), r.height(), dirtyRect.width(), dirtyRect.height(),
|
||||
dirtyRect.x(), dirtyRect.y());
|
||||
} else {
|
||||
const HDC dc = rw->getDC();
|
||||
if (!dc) {
|
||||
|
@ -237,8 +237,7 @@ void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, L
|
||||
return;
|
||||
// In rare cases, a clipboard viewer can hang (application crashed,
|
||||
// suspended by a shell prompt 'Select' or debugger).
|
||||
if (QWindowsContext::user32dll.isHungAppWindow
|
||||
&& QWindowsContext::user32dll.isHungAppWindow(m_nextClipboardViewer)) {
|
||||
if (IsHungAppWindow(m_nextClipboardViewer)) {
|
||||
qWarning("Cowardly refusing to send clipboard message to hung application...");
|
||||
return;
|
||||
}
|
||||
|
@ -97,35 +97,26 @@ int QWindowsContext::verbose = 0;
|
||||
# define LANG_SYRIAC 0x5a
|
||||
#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
|
||||
// Vista, check the Keyboard Layouts for enabling RTL.
|
||||
if (const int nLayouts = GetKeyboardLayoutList(0, 0)) {
|
||||
QScopedArrayPointer<HKL> lpList(new HKL[nLayouts]);
|
||||
GetKeyboardLayoutList(nLayouts, lpList.data());
|
||||
for (int i = 0; i < nLayouts; ++i) {
|
||||
switch (PRIMARYLANGID((quintptr)lpList[i])) {
|
||||
case LANG_ARABIC:
|
||||
case LANG_HEBREW:
|
||||
case LANG_FARSI:
|
||||
case LANG_SYRIAC:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Since the IsValidLanguageGroup/IsValidLocale functions always return true on
|
||||
// Vista, check the Keyboard Layouts for enabling RTL.
|
||||
if (const int nLayouts = GetKeyboardLayoutList(0, 0)) {
|
||||
QScopedArrayPointer<HKL> lpList(new HKL[nLayouts]);
|
||||
GetKeyboardLayoutList(nLayouts, lpList.data());
|
||||
for (int i = 0; i < nLayouts; ++i) {
|
||||
switch (PRIMARYLANGID((quintptr)lpList[i])) {
|
||||
case LANG_ARABIC:
|
||||
case LANG_HEBREW:
|
||||
case LANG_FARSI:
|
||||
case LANG_SYRIAC:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} // NT/Vista
|
||||
// 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);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_SESSIONMANAGER)
|
||||
@ -152,9 +143,7 @@ static inline QWindowsSessionManager *platformSessionManager() {
|
||||
\ingroup qt-lighthouse-win
|
||||
*/
|
||||
QWindowsUser32DLL::QWindowsUser32DLL() :
|
||||
setLayeredWindowAttributes(0), updateLayeredWindow(0),
|
||||
updateLayeredWindowIndirect(0),
|
||||
isHungAppWindow(0), isTouchWindow(0),
|
||||
isTouchWindow(0),
|
||||
registerTouchWindow(0), unregisterTouchWindow(0),
|
||||
getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0),
|
||||
addClipboardFormatListener(0), removeClipboardFormatListener(0),
|
||||
@ -165,20 +154,11 @@ QWindowsUser32DLL::QWindowsUser32DLL() :
|
||||
void QWindowsUser32DLL::init()
|
||||
{
|
||||
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");
|
||||
|
||||
if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) {
|
||||
addClipboardFormatListener = (AddClipboardFormatListener)library.resolve("AddClipboardFormatListener");
|
||||
removeClipboardFormatListener = (RemoveClipboardFormatListener)library.resolve("RemoveClipboardFormatListener");
|
||||
}
|
||||
addClipboardFormatListener = (AddClipboardFormatListener)library.resolve("AddClipboardFormatListener");
|
||||
removeClipboardFormatListener = (RemoveClipboardFormatListener)library.resolve("RemoveClipboardFormatListener");
|
||||
|
||||
getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences");
|
||||
setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences");
|
||||
}
|
||||
@ -196,38 +176,6 @@ bool QWindowsUser32DLL::initTouch()
|
||||
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()
|
||||
: getProcessDpiAwareness(0)
|
||||
, setProcessDpiAwareness(0)
|
||||
@ -246,7 +194,6 @@ void QWindowsShcoreDLL::init()
|
||||
}
|
||||
|
||||
QWindowsUser32DLL QWindowsContext::user32dll;
|
||||
QWindowsShell32DLL QWindowsContext::shell32dll;
|
||||
QWindowsShcoreDLL QWindowsContext::shcoredll;
|
||||
|
||||
QWindowsContext *QWindowsContext::m_instance = 0;
|
||||
@ -292,16 +239,14 @@ QWindowsContextPrivate::QWindowsContextPrivate()
|
||||
, m_eventType(QByteArrayLiteral("windows_generic_MSG"))
|
||||
, m_lastActiveWindow(0), m_asyncExpose(0)
|
||||
{
|
||||
const QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
|
||||
QWindowsContext::user32dll.init();
|
||||
QWindowsContext::shell32dll.init();
|
||||
QWindowsContext::shcoredll.init();
|
||||
|
||||
if (m_mouseHandler.touchDevice() && QWindowsContext::user32dll.initTouch())
|
||||
m_systemInfo |= QWindowsContext::SI_SupportsTouch;
|
||||
m_displayContext = GetDC(0);
|
||||
m_defaultDPI = GetDeviceCaps(m_displayContext, LOGPIXELSY);
|
||||
if (useRTL_Extensions(ver)) {
|
||||
if (useRTL_Extensions()) {
|
||||
m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
|
||||
m_keyMapper.setUseRTLExtensions(true);
|
||||
}
|
||||
|
@ -85,31 +85,17 @@ struct QWindowsUser32DLL
|
||||
inline void init();
|
||||
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 *UnregisterTouchWindow)(HWND);
|
||||
typedef BOOL (WINAPI *GetTouchInputInfo)(HANDLE, UINT, PVOID, int);
|
||||
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 *AddClipboardFormatListener)(HWND);
|
||||
typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
|
||||
typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(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).
|
||||
IsTouchWindow isTouchWindow;
|
||||
RegisterTouchWindow registerTouchWindow;
|
||||
@ -120,7 +106,8 @@ struct QWindowsUser32DLL
|
||||
// Windows Vista onwards
|
||||
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;
|
||||
RemoveClipboardFormatListener removeClipboardFormatListener;
|
||||
|
||||
@ -129,24 +116,6 @@ struct QWindowsUser32DLL
|
||||
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)
|
||||
struct QWindowsShcoreDLL {
|
||||
QWindowsShcoreDLL();
|
||||
@ -235,7 +204,6 @@ public:
|
||||
QWindowsTabletSupport *tabletSupport() const;
|
||||
|
||||
static QWindowsUser32DLL user32dll;
|
||||
static QWindowsShell32DLL shell32dll;
|
||||
static QWindowsShcoreDLL shcoredll;
|
||||
|
||||
static QByteArray comErrorString(HRESULT hr);
|
||||
|
@ -988,22 +988,18 @@ void QWindowsNativeFileDialogBase::setWindowTitle(const QString &title)
|
||||
IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url)
|
||||
{
|
||||
if (url.isLocalFile()) {
|
||||
if (!QWindowsContext::shell32dll.sHCreateItemFromParsingName)
|
||||
return Q_NULLPTR;
|
||||
IShellItem *result = Q_NULLPTR;
|
||||
const QString native = QDir::toNativeSeparators(url.toLocalFile());
|
||||
const HRESULT hr =
|
||||
QWindowsContext::shell32dll.sHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
|
||||
NULL, IID_IShellItem,
|
||||
reinterpret_cast<void **>(&result));
|
||||
SHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
|
||||
NULL, IID_IShellItem,
|
||||
reinterpret_cast<void **>(&result));
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning("%s: SHCreateItemFromParsingName(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
return result;
|
||||
} else if (url.scheme() == QLatin1String("clsid")) {
|
||||
if (!QWindowsContext::shell32dll.sHGetKnownFolderIDList || !QWindowsContext::shell32dll.sHCreateItemFromIDList)
|
||||
return Q_NULLPTR;
|
||||
// Support for virtual folders via GUID
|
||||
// (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx)
|
||||
// specified as "clsid:<GUID>" (without '{', '}').
|
||||
@ -1014,12 +1010,12 @@ IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url)
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
PIDLIST_ABSOLUTE idList;
|
||||
HRESULT hr = QWindowsContext::shell32dll.sHGetKnownFolderIDList(uuid, 0, 0, &idList);
|
||||
HRESULT hr = SHGetKnownFolderIDList(uuid, 0, 0, &idList);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning("%s: SHGetKnownFolderIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
|
||||
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);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning("%s: SHCreateItemFromIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
|
||||
|
@ -490,7 +490,7 @@ 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;
|
||||
SHSTOCKICONID stockId = SIID_INVALID;
|
||||
UINT stockFlags = 0;
|
||||
LPCTSTR iconName = 0;
|
||||
switch (sp) {
|
||||
@ -577,20 +577,16 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
|
||||
}
|
||||
|
||||
if (stockId != SIID_INVALID) {
|
||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
|
||||
&& (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
|
||||
&& QWindowsContext::shell32dll.sHGetStockIconInfo) {
|
||||
QPixmap pixmap;
|
||||
SHSTOCKICONINFO iconInfo;
|
||||
memset(&iconInfo, 0, sizeof(iconInfo));
|
||||
iconInfo.cbSize = sizeof(iconInfo);
|
||||
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;
|
||||
}
|
||||
QPixmap pixmap;
|
||||
SHSTOCKICONINFO iconInfo;
|
||||
memset(&iconInfo, 0, sizeof(iconInfo));
|
||||
iconInfo.cbSize = sizeof(iconInfo);
|
||||
stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON);
|
||||
if (SHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) {
|
||||
pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
|
||||
pixmap.setDevicePixelRatio(scaleFactor);
|
||||
DestroyIcon(iconInfo.hIcon);
|
||||
return pixmap;
|
||||
}
|
||||
}
|
||||
|
||||
@ -669,14 +665,8 @@ static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info)
|
||||
// For MinGW:
|
||||
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;
|
||||
HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList,
|
||||
reinterpret_cast<void **>(&imageList));
|
||||
HRESULT hr = SHGetImageList(iImageList, iID_IImageList, reinterpret_cast<void **>(&imageList));
|
||||
if (hr != S_OK)
|
||||
return result;
|
||||
HICON hIcon;
|
||||
|
@ -62,6 +62,8 @@
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <dwmapi.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum {
|
||||
@ -258,55 +260,22 @@ static inline bool windowIsOpenGL(const QWindow *w)
|
||||
|
||||
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;
|
||||
if (dwmIsCompositionEnabled(&compositionEnabled) != S_OK)
|
||||
if (DwmIsCompositionEnabled(&compositionEnabled) != S_OK)
|
||||
return false;
|
||||
|
||||
DwmBlurBehind blurBehind = {0, 0, 0, 0};
|
||||
DWM_BLURBEHIND blurBehind = {0, 0, 0, 0};
|
||||
|
||||
if (compositionEnabled) {
|
||||
blurBehind.dwFlags = dwmBbEnable | dwmBbBlurRegion;
|
||||
blurBehind.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||
blurBehind.fEnable = TRUE;
|
||||
blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
|
||||
} else {
|
||||
blurBehind.dwFlags = dwmBbEnable;
|
||||
blurBehind.dwFlags = DWM_BB_ENABLE;
|
||||
blurBehind.fEnable = FALSE;
|
||||
}
|
||||
|
||||
const bool result = dwmBlurBehind(hwnd, &blurBehind) == S_OK;
|
||||
const bool result = DwmEnableBlurBehindWindow(hwnd, &blurBehind) == S_OK;
|
||||
|
||||
if (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)) {
|
||||
// Non-GL windows with alpha: Use blend function to update.
|
||||
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 {
|
||||
QWindowsContext::user32dll.setLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA);
|
||||
SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA);
|
||||
}
|
||||
} else if (IsWindowVisible(hwnd)) { // Repaint when switching from layered.
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
|
@ -4,7 +4,7 @@ QT *= core-private
|
||||
QT *= gui-private
|
||||
QT *= platformsupport-private
|
||||
|
||||
LIBS += -lgdi32
|
||||
LIBS += -lgdi32 -ldwmapi
|
||||
|
||||
include(windows.pri)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user