Skip to content

Commit

Permalink
Use large program icons on Windows
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
HeikoKlare committed Feb 2, 2024
1 parent 539fa36 commit f5ed487
Showing 1 changed file with 25 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;

Expand Down Expand Up @@ -377,6 +378,21 @@ public ImageData getImageData () {
* @since 3.125
*/
public ImageData getImageData (int zoom) {
boolean useLargeIcon = zoom > 100;
ElementAtZoom<Image> 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<Image> loadIcon(boolean useLargeIconIfAvailable) {
int nIconIndex = 0;
String fileName = iconName;
int index = iconName.indexOf (',');
Expand All @@ -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;
}

/**
Expand Down

0 comments on commit f5ed487

Please sign in to comment.