diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java index c3cfd904f28..7fd6d49f013 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java @@ -1196,6 +1196,7 @@ public class OS extends C { public static final int SET_FEATURE_ON_PROCESS = 0x2; public static final int SHADEBLENDCAPS = 120; public static final int SHGFI_ICON = 0x000000100; + public static final int SHGFI_LARGEICON= 0x0; public static final int SHGFI_SMALLICON= 0x1; public static final int SHGFI_USEFILEATTRIBUTES = 0x000000010; public static final int SIGDN_FILESYSPATH = 0x80058000; 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 a5d483c30fb..a0aeef36ea8 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.*; @@ -382,20 +383,50 @@ public ImageData getImageData () { public ImageData getImageData (int zoom) { // 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(); + int primaryMonitorZoom = Display.getCurrent().getPrimaryMonitor().getZoom(); + int nativeZoomFactor = 100 * primaryMonitorZoom / DPIUtil.getDeviceZoom(); int imageZoomFactor = 100 * zoom / nativeZoomFactor; + // Use small icon if expected icon size is less than 150% of delivered icon size + // and use large icon if it is more than 150% of the delivered icon size + boolean useLargeIcon = 100 * zoom / primaryMonitorZoom > 200; + ElementAtZoom zoomedIcon = null; if (extension != null) { - SHFILEINFO shfi = new SHFILEINFO (); - int flags = OS.SHGFI_ICON | OS.SHGFI_SMALLICON | OS.SHGFI_USEFILEATTRIBUTES; - TCHAR pszPath = new TCHAR (0, extension, true); - OS.SHGetFileInfo (pszPath.chars, OS.FILE_ATTRIBUTE_NORMAL, shfi, SHFILEINFO.sizeof, flags); + zoomedIcon = loadIconForFileExtension(useLargeIcon); + } + if (zoomedIcon == null) { + zoomedIcon = loadIconForFile(useLargeIcon); + } + if (zoomedIcon != null) { + Image image = zoomedIcon.element(); + ImageData imageData = image.getImageData (imageZoomFactor * 100 / zoomedIcon.zoom()); + image.dispose (); + return imageData; + } + return null; +} + +private ElementAtZoom loadIconForFileExtension(boolean useLargeIconIfAvailable) { + SHFILEINFO shfi = new SHFILEINFO (); + TCHAR pszPath = new TCHAR (0, extension, true); + int flags = OS.SHGFI_ICON | OS.SHGFI_USEFILEATTRIBUTES; + int iconZoom = 100; + if (useLargeIconIfAvailable) { + OS.SHGetFileInfo (pszPath.chars, OS.FILE_ATTRIBUTE_NORMAL, shfi, SHFILEINFO.sizeof, flags | OS.SHGFI_LARGEICON); if (shfi.hIcon != 0) { - Image image = Image.win32_new (null, SWT.ICON, shfi.hIcon); - ImageData imageData = image.getImageData (imageZoomFactor); - image.dispose (); - return imageData; + iconZoom = 200; } } + if (shfi.hIcon == 0) { + OS.SHGetFileInfo (pszPath.chars, OS.FILE_ATTRIBUTE_NORMAL, shfi, SHFILEINFO.sizeof, flags | OS.SHGFI_SMALLICON); + } + if (shfi.hIcon != 0) { + Image image = Image.win32_new (null, SWT.ICON, shfi.hIcon); + return new ElementAtZoom<>(image, iconZoom); + } + return null; +} + +private ElementAtZoom loadIconForFile(boolean useLargeIconIfAvailable) { int nIconIndex = 0; String fileName = iconName; int index = iconName.indexOf (','); @@ -414,12 +445,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]); - ImageData imageData = image.getImageData (imageZoomFactor); - 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; } /**