From f5ed487c62a3e33f9dfd88cd6d04e6a4f530afd0 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 30 Jan 2024 12:32:10 +0100 Subject: [PATCH] Use large program icons on Windows Icons for files associated with an external program area always loaded in small size using the Windows API. The API also provides an option to load large icons, which have twice the size of the small ones. In order to improve the icon sharpness when retrieving the icon for (monitor) scale value of more than 100%, this change ensures that the higher resolution icon is used and scaled appropriately. --- .../org/eclipse/swt/program/Program.java | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Program/win32/org/eclipse/swt/program/Program.java b/bundles/org.eclipse.swt/Eclipse SWT Program/win32/org/eclipse/swt/program/Program.java index b5a2b6252a9..c34c827a703 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Program/win32/org/eclipse/swt/program/Program.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Program/win32/org/eclipse/swt/program/Program.java @@ -20,6 +20,7 @@ import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.DPIUtil.*; import org.eclipse.swt.internal.win32.*; import org.eclipse.swt.widgets.*; @@ -377,6 +378,21 @@ public ImageData getImageData () { * @since 3.125 */ public ImageData getImageData (int zoom) { + boolean useLargeIcon = zoom > 100; + ElementAtZoom zoomedIcon = loadIcon(useLargeIcon); + if (zoomedIcon == null) { + return null; + } + // Windows API returns image data according to primary monitor zoom factor + // rather than at original scaling + int nativeZoomFactor = zoomedIcon.zoom() * Display.getCurrent().getPrimaryMonitor().getZoom() / DPIUtil.getDeviceZoom(); + Image image = zoomedIcon.element(); + ImageData imageData = image.getImageData (100 * zoom / nativeZoomFactor); + image.dispose (); + return imageData; +} + +private ElementAtZoom loadIcon(boolean useLargeIconIfAvailable) { int nIconIndex = 0; String fileName = iconName; int index = iconName.indexOf (','); @@ -395,15 +411,16 @@ public ImageData getImageData (int zoom) { } TCHAR lpszFile = new TCHAR (0, fileName, true); long [] phiconSmall = new long[1], phiconLarge = null; + if (useLargeIconIfAvailable) { + phiconLarge = new long[1]; + } OS.ExtractIconEx (lpszFile, nIconIndex, phiconLarge, phiconSmall, 1); - if (phiconSmall [0] == 0) return null; - Image image = Image.win32_new (null, SWT.ICON, phiconSmall [0]); - // Windows API returns image data according to primary monitor zoom factor - // rather than at original scaling - int nativeZoomFactor = 100 * Display.getCurrent().getPrimaryMonitor().getZoom() / DPIUtil.getDeviceZoom(); - ImageData imageData = image.getImageData (100 * zoom / nativeZoomFactor); - image.dispose (); - return imageData; + if (useLargeIconIfAvailable && phiconLarge[0] != 0) { + return new ElementAtZoom<>(Image.win32_new (null, SWT.ICON, phiconLarge[0]), 200); + } else if (phiconSmall[0] != 0) { + return new ElementAtZoom<>(Image.win32_new (null, SWT.ICON, phiconSmall[0]), 100); + } + return null; } /**