Windows: Return high-DPI pixmaps from QWindowsTheme::standardPixmap
Most consumers feed the pixmaps into a QIcon, pulling out pixmaps of sizes 32, 64, 128, 256, 512, so consumers of that QIcon will not see low-resolution pixmaps for the common sizes like 64x64. However if someone uses standardPixmap directly, or request an icon with size 512x512, we won't have a high-DPI pixmap. Unlike QStyle::standardPixmap we don't have a QWidget/QWindow argument we can use to resolve the target DPR, so we have to assume the pixmap can be used anywhere, and use the highest DPR we've seen so far, via QGuiApplication::devicePixelRatio(). Pick-to: 6.9 Change-Id: Ib7fb08ab4932da1ca3f3325e25a7022c1cd17435 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
9b924a4907
commit
59bbfb17db
@ -803,12 +803,12 @@ void QWindowsTheme::refreshIconPixmapSizes()
|
||||
// Defined in qpixmap_win.cpp
|
||||
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon);
|
||||
|
||||
static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
|
||||
static QPixmap loadIconFromShell32(int resourceId, QSize size)
|
||||
{
|
||||
if (const HMODULE hmod = QSystemLibrary::load(L"shell32")) {
|
||||
auto iconHandle =
|
||||
static_cast<HICON>(LoadImage(hmod, MAKEINTRESOURCE(resourceId),
|
||||
IMAGE_ICON, int(size.width()), int(size.height()), 0));
|
||||
IMAGE_ICON, size.width(), size.height(), 0));
|
||||
if (iconHandle) {
|
||||
QPixmap iconpixmap = qt_pixmapFromWinHICON(iconHandle);
|
||||
DestroyIcon(iconHandle);
|
||||
@ -818,7 +818,7 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSize) const
|
||||
QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
|
||||
{
|
||||
int resourceId = -1;
|
||||
SHSTOCKICONID stockId = SIID_INVALID;
|
||||
@ -907,16 +907,19 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
|
||||
break;
|
||||
}
|
||||
|
||||
const auto dpr = qGuiApp->devicePixelRatio(); // Highest in the system
|
||||
|
||||
if (stockId != SIID_INVALID) {
|
||||
SHSTOCKICONINFO iconInfo;
|
||||
memset(&iconInfo, 0, sizeof(iconInfo));
|
||||
iconInfo.cbSize = sizeof(iconInfo);
|
||||
stockFlags |= SHGSI_ICONLOCATION;
|
||||
if (SHGetStockIconInfo(stockId, stockFlags, &iconInfo) == S_OK) {
|
||||
const auto iconSize = pixmapSize.width();
|
||||
const auto iconSize = size.width() * dpr;
|
||||
HICON icon;
|
||||
if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &icon, nullptr, iconSize) == S_OK) {
|
||||
QPixmap pixmap = qt_pixmapFromWinHICON(icon);
|
||||
pixmap.setDevicePixelRatio(dpr);
|
||||
DestroyIcon(icon);
|
||||
return pixmap;
|
||||
}
|
||||
@ -924,13 +927,15 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
|
||||
}
|
||||
|
||||
if (resourceId != -1) {
|
||||
const QSize pixmapSize(size.width() * dpr, size.height() * dpr);
|
||||
QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);
|
||||
if (!pixmap.isNull()) {
|
||||
if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) {
|
||||
QPainter painter(&pixmap);
|
||||
QPixmap link = loadIconFromShell32(30, pixmapSize);
|
||||
painter.drawPixmap(0, 0, int(pixmapSize.width()), int(pixmapSize.height()), link);
|
||||
painter.drawPixmap(0, 0, pixmapSize.width(), pixmapSize.height(), link);
|
||||
}
|
||||
pixmap.setDevicePixelRatio(dpr);
|
||||
return pixmap;
|
||||
}
|
||||
}
|
||||
@ -943,7 +948,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
return QPlatformTheme::standardPixmap(sp, pixmapSize);
|
||||
return QPlatformTheme::standardPixmap(sp, size);
|
||||
}
|
||||
|
||||
enum { // Shell image list ids
|
||||
|
Loading…
x
Reference in New Issue
Block a user