@@ -781,8 +781,7 @@ public void setImage (Image image) {
781
781
info .hbmpItem = OS .HBMMENU_CALLBACK ;
782
782
} else {
783
783
if (OS .IsAppThemed ()) {
784
- if (hBitmap != 0 ) OS .DeleteObject (hBitmap );
785
- info .hbmpItem = hBitmap = image != null ? Display .create32bitDIB (image , getZoom ()) : 0 ;
784
+ info .hbmpItem = hBitmap = getMenuItemIconBitmapHandle (image );
786
785
} else {
787
786
info .hbmpItem = image != null ? OS .HBMMENU_CALLBACK : 0 ;
788
787
}
@@ -792,6 +791,52 @@ public void setImage (Image image) {
792
791
parent .redraw ();
793
792
}
794
793
794
+ private long getMenuItemIconBitmapHandle (Image image ) {
795
+ if (image == null ) {
796
+ return 0 ;
797
+ }
798
+ if (hBitmap != 0 ) OS .DeleteObject (hBitmap );
799
+ int zoom = adaptZoomForMenuItem (getZoom ());
800
+ return Display .create32bitDIB (image , zoom );
801
+ }
802
+
803
+ private int adaptZoomForMenuItem (int currentZoom ) {
804
+ int primaryMonitorZoomAtAppStartUp = getPrimaryMonitorZoomAtStartup ();
805
+ /*
806
+ * Windows has inconsistent behavior when setting the size of MenuItem image and
807
+ * hence we need to adjust the size of the images as per different kind of zoom
808
+ * level, i.e. full (100s), half (50s) and quarter (25s). The image size per
809
+ * zoom level is also affected by the primaryMonitorZoomAtAppStartUp. The
810
+ * implementation below is based on the pattern observed for all the zoom values
811
+ * and what fits the best for these zoom level types.
812
+ */
813
+ if (primaryMonitorZoomAtAppStartUp > currentZoom && isQuarterZoom (currentZoom )) {
814
+ return currentZoom - 25 ;
815
+ }
816
+ if (!isHalfZoom (primaryMonitorZoomAtAppStartUp ) && isHalfZoom (currentZoom )) {
817
+ // Use the size recommended by System Metrics. This value only holds
818
+ // for this case and does not work consistently for other cases.
819
+ double expectedSize = getSystemMetrics (OS .SM_CYMENUCHECK );
820
+ return (int ) ((expectedSize / image .getBounds ().height ) * 100 );
821
+ }
822
+ return currentZoom ;
823
+ }
824
+
825
+ private static boolean isHalfZoom (int zoom ) {
826
+ return zoom % 50 == 0 && zoom % 100 != 0 ;
827
+ }
828
+
829
+ private static boolean isQuarterZoom (int zoom ) {
830
+ return zoom % 10 != 0 && zoom % 25 == 0 ;
831
+ }
832
+
833
+ private static int getPrimaryMonitorZoomAtStartup () {
834
+ long hDC = OS .GetDC (0 );
835
+ int dpi = OS .GetDeviceCaps (hDC , OS .LOGPIXELSX );
836
+ OS .ReleaseDC (0 , hDC );
837
+ return DPIUtil .mapDPIToZoom (dpi );
838
+ }
839
+
795
840
/**
796
841
* Sets the receiver's pull down menu to the argument.
797
842
* Only <code>CASCADE</code> menu items can have a
0 commit comments