From 18369fb72e572493522e3ac29c20bb4030d4a3cc Mon Sep 17 00:00:00 2001 From: Thomas Singer Date: Thu, 21 Mar 2024 11:32:59 +0100 Subject: [PATCH] #1130: [Win32]: Program.getImageData is broken for ".exe" extension Before commit 97ca656d `SHGetFileInfo` was used initially to get the icon. This caused problems for some icons (#715). The fix in commit 97ca656d removed the `SHGetFileInfo` invocation which caused a new problem that for some file extensions, e.g. `.exe`, no icon was returned any more. This fix re-introduces the `SHGetFileInfo`, but only uses it if `ExtractIconEx` did not return an icon. See: #1030: https://github.com/eclipse-platform/eclipse.platform.swt/issues/1130 #715: https://github.com/eclipse-platform/eclipse.platform.swt/issues/715 --- .../org/eclipse/swt/program/Program.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 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..5a755d55caf 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 @@ -35,6 +35,7 @@ public final class Program { String name; String command; String iconName; + String extension; static final String [] ARGUMENTS = new String [] {"%1", "%l", "%L"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ /** @@ -101,6 +102,7 @@ public static Program findProgram (String extension) { program.name = name; program.command = command; program.iconName = iconName; + program.extension = extension; } return program; } @@ -182,7 +184,7 @@ static String getKeyValue (String string, boolean expand) { return result; } -static Program getProgram (String key) { +static Program getProgram (String key, String extension) { /* Name */ String name = getKeyValue (key, false); @@ -208,6 +210,7 @@ static Program getProgram (String key) { program.name = name; program.command = command; program.iconName = iconName; + program.extension = extension; return program; } @@ -233,7 +236,7 @@ static Program getProgram (String key) { //map paths to programs in parallel which takes now ~ 4/5 of time: ConcurrentHashMap programs = new ConcurrentHashMap<>(paths.size()); paths.stream().parallel().forEach(path -> { - Program program = getProgram(path); // getProgram takes most time + Program program = getProgram(path, null); // getProgram takes most time if (program != null) { programs.put(path, program); } @@ -396,8 +399,22 @@ public ImageData getImageData (int zoom) { TCHAR lpszFile = new TCHAR (0, fileName, true); long [] phiconSmall = new long[1], phiconLarge = null; OS.ExtractIconEx (lpszFile, nIconIndex, phiconLarge, phiconSmall, 1); - if (phiconSmall [0] == 0) return null; - Image image = Image.win32_new (null, SWT.ICON, phiconSmall [0]); + + long hIcon = phiconSmall [0]; + + if (hIcon == 0) { + 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); + + hIcon = shfi.hIcon; + + if (hIcon == 0) return null; + } + + + Image image = Image.win32_new (null, SWT.ICON, hIcon); // 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();