Draw icon overlay manually instead of relying on the api
Even with SHGSI_LINKOVERLAY flag set, loaded Icon with SHDefExtractIcon doesn't have any overlay, so we draw it manually. Pick-to: 6.9 6.8 Fixes: QTBUG-131843 Change-Id: Iae4c2da12104a361b9a8cf05c78adcdb698f1f82 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
This commit is contained in:
parent
8f2f4ad468
commit
fd7bc16e9f
@ -822,7 +822,6 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
|
|||||||
{
|
{
|
||||||
int resourceId = -1;
|
int resourceId = -1;
|
||||||
SHSTOCKICONID stockId = SIID_INVALID;
|
SHSTOCKICONID stockId = SIID_INVALID;
|
||||||
UINT stockFlags = 0;
|
|
||||||
LPCTSTR iconName = nullptr;
|
LPCTSTR iconName = nullptr;
|
||||||
switch (sp) {
|
switch (sp) {
|
||||||
case DriveCDIcon:
|
case DriveCDIcon:
|
||||||
@ -846,14 +845,12 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
|
|||||||
resourceId = 7;
|
resourceId = 7;
|
||||||
break;
|
break;
|
||||||
case FileLinkIcon:
|
case FileLinkIcon:
|
||||||
stockFlags = SHGSI_LINKOVERLAY;
|
|
||||||
Q_FALLTHROUGH();
|
Q_FALLTHROUGH();
|
||||||
case FileIcon:
|
case FileIcon:
|
||||||
stockId = SIID_DOCNOASSOC;
|
stockId = SIID_DOCNOASSOC;
|
||||||
resourceId = 1;
|
resourceId = 1;
|
||||||
break;
|
break;
|
||||||
case DirLinkIcon:
|
case DirLinkIcon:
|
||||||
stockFlags = SHGSI_LINKOVERLAY;
|
|
||||||
Q_FALLTHROUGH();
|
Q_FALLTHROUGH();
|
||||||
case DirClosedIcon:
|
case DirClosedIcon:
|
||||||
case DirIcon:
|
case DirIcon:
|
||||||
@ -867,7 +864,6 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
|
|||||||
resourceId = 16;
|
resourceId = 16;
|
||||||
break;
|
break;
|
||||||
case DirLinkOpenIcon:
|
case DirLinkOpenIcon:
|
||||||
stockFlags = SHGSI_LINKOVERLAY;
|
|
||||||
Q_FALLTHROUGH();
|
Q_FALLTHROUGH();
|
||||||
case DirOpenIcon:
|
case DirOpenIcon:
|
||||||
stockId = SIID_FOLDEROPEN;
|
stockId = SIID_FOLDEROPEN;
|
||||||
@ -907,16 +903,34 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Even with SHGSI_LINKOVERLAY flag set, loaded Icon with SHDefExtractIcon doesn't have
|
||||||
|
// any overlay, so we avoid SHGSI_LINKOVERLAY flag and draw it manually (QTBUG-131843)
|
||||||
|
const auto drawLinkOverlayIcon = [](StandardPixmap sp, QPixmap &pixmap, QSizeF pixmapSize) {
|
||||||
|
if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) {
|
||||||
|
QPainter painter(&pixmap);
|
||||||
|
const QSizeF linkSize = pixmapSize / (pixmapSize.height() >= 48 ? 3 : 2);
|
||||||
|
const QPixmap link = loadIconFromShell32(16769, linkSize.toSize()); // 16769 = LinkOverlayIcon
|
||||||
|
const int yPos = pixmap.height() - link.size().height();
|
||||||
|
painter.drawPixmap(0, yPos, int(linkSize.width()), int(linkSize.height()), link);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto dpr = qGuiApp->devicePixelRatio(); // Highest in the system
|
||||||
|
|
||||||
if (stockId != SIID_INVALID) {
|
if (stockId != SIID_INVALID) {
|
||||||
SHSTOCKICONINFO iconInfo;
|
SHSTOCKICONINFO iconInfo;
|
||||||
memset(&iconInfo, 0, sizeof(iconInfo));
|
memset(&iconInfo, 0, sizeof(iconInfo));
|
||||||
iconInfo.cbSize = sizeof(iconInfo);
|
iconInfo.cbSize = sizeof(iconInfo);
|
||||||
stockFlags |= SHGSI_ICONLOCATION;
|
constexpr UINT stockFlags = SHGSI_ICONLOCATION;
|
||||||
if (SHGetStockIconInfo(stockId, stockFlags, &iconInfo) == S_OK) {
|
if (SHGetStockIconInfo(stockId, stockFlags, &iconInfo) == S_OK) {
|
||||||
const auto iconSize = pixmapSize.width();
|
const auto iconSize = pixmapSize.width();
|
||||||
HICON icon;
|
HICON icon;
|
||||||
if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &icon, nullptr, iconSize) == S_OK) {
|
if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &icon, nullptr, iconSize) == S_OK) {
|
||||||
QPixmap pixmap = qt_pixmapFromWinHICON(icon);
|
QPixmap pixmap = qt_pixmapFromWinHICON(icon);
|
||||||
|
if (!pixmap.isNull()) {
|
||||||
|
drawLinkOverlayIcon(sp, pixmap, pixmap.size());
|
||||||
|
pixmap.setDevicePixelRatio(dpr);
|
||||||
|
}
|
||||||
DestroyIcon(icon);
|
DestroyIcon(icon);
|
||||||
return pixmap;
|
return pixmap;
|
||||||
}
|
}
|
||||||
@ -926,11 +940,8 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
|
|||||||
if (resourceId != -1) {
|
if (resourceId != -1) {
|
||||||
QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);
|
QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);
|
||||||
if (!pixmap.isNull()) {
|
if (!pixmap.isNull()) {
|
||||||
if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) {
|
drawLinkOverlayIcon(sp, pixmap, pixmapSize);
|
||||||
QPainter painter(&pixmap);
|
pixmap.setDevicePixelRatio(dpr);
|
||||||
QPixmap link = loadIconFromShell32(30, pixmapSize);
|
|
||||||
painter.drawPixmap(0, 0, int(pixmapSize.width()), int(pixmapSize.height()), link);
|
|
||||||
}
|
|
||||||
return pixmap;
|
return pixmap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user