< prev index next >

src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp

Print this page
rev 13901 : Fixes for 8151385. Contains additional fix for 8149453 (upFolder, newFolder, etc. icons)
rev 13644 : 8080492: [Parfait] Uninitialised variable in jdk/src/java/desktop/windows/native/libawt/
Reviewed-by: prr, vadim
rev 12267 : 8022057: JFileChooser blocks EDT in Win32ShellFolder2.getIcon
Reviewed-by: serb, ant
rev 12120 : 8081231: JDK9 client build broken on Windows
Reviewed-by: azvegint
rev 12117 : 8003399: JFileChooser gives wrong path to selected file when saving to Libraries folder on Windows 7
Reviewed-by: serb, ant
rev 10731 : 8056216: Remove "sun" directory layer from libawt and common
Reviewed-by: erikj, ihse, coffeys

@@ -928,23 +928,47 @@
 }
 
 /*
  * Class:     sun_awt_shell_Win32ShellFolder2
  * Method:    getIconBits
- * Signature: (JI)[I
+ * Signature: (J)[I
  */
 JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
-    (JNIEnv* env, jclass cls, jlong hicon, jint iconSize)
+    (JNIEnv* env, jclass cls, jlong hicon)
 {
+    const int MAX_ICON_SIZE = 128;
+    int iconSize = 0;
     jintArray iconBits = NULL;
 
+    BITMAP bmp;
+    memset(&bmp, 0, sizeof(BITMAP));
+
     // Get the icon info
     ICONINFO iconInfo;
     if (fn_GetIconInfo((HICON)hicon, &iconInfo)) {
         // Get the screen DC
         HDC dc = GetDC(NULL);
         if (dc != NULL) {
+            // find out the icon size in order to deal with different sizes
+            // delivered depending on HiDPI mode or SD DPI mode.
+            if (iconInfo.hbmColor) {
+                const int nWrittenBytes = GetObject(iconInfo.hbmColor, sizeof(bmp), &bmp);
+                if(nWrittenBytes > 0) {
+                    iconSize = bmp.bmWidth;
+                }
+            } else if (iconInfo.hbmMask) {
+                // Icon has no color plane, image data stored in mask
+                const int nWrittenBytes = GetObject(iconInfo.hbmMask, sizeof(bmp), &bmp);
+                if (nWrittenBytes > 0) {
+                    iconSize = bmp.bmWidth;
+                }
+            }
+            // limit iconSize to MAX_ICON_SIZE, so that the colorBits and maskBits
+            // arrays are big enough.
+            // (logic: rather show bad icons than overrun the array size)
+            iconSize = iconSize > MAX_ICON_SIZE ? MAX_ICON_SIZE : iconSize;
+
             // Set up BITMAPINFO
             BITMAPINFO bmi;
             memset(&bmi, 0, sizeof(BITMAPINFO));
             bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
             bmi.bmiHeader.biWidth = iconSize;

@@ -952,11 +976,11 @@
             bmi.bmiHeader.biPlanes = 1;
             bmi.bmiHeader.biBitCount = 32;
             bmi.bmiHeader.biCompression = BI_RGB;
             // Extract the color bitmap
             int nBits = iconSize * iconSize;
-            long colorBits[1024];
+            long colorBits[MAX_ICON_SIZE * MAX_ICON_SIZE];
             GetDIBits(dc, iconInfo.hbmColor, 0, iconSize, colorBits, &bmi, DIB_RGB_COLORS);
             // XP supports alpha in some icons, and depending on device.
             // This should take precedence over the icon mask bits.
             BOOL hasAlpha = FALSE;
             if (IS_WINXP) {

@@ -967,11 +991,11 @@
                     }
                 }
             }
             if (!hasAlpha) {
                 // Extract the mask bitmap
-                long maskBits[1024];
+                long maskBits[MAX_ICON_SIZE * MAX_ICON_SIZE];
                 GetDIBits(dc, iconInfo.hbmMask, 0, iconSize, maskBits, &bmi, DIB_RGB_COLORS);
                 // Copy the mask alphas into the color bits
                 for (int i = 0; i < nBits; i++) {
                     if (maskBits[i] == 0) {
                         colorBits[i] |= 0xff000000;

@@ -1002,29 +1026,30 @@
  * Class:     sun_awt_shell_Win32ShellFolder2
  * Method:    getStandardViewButton0
  * Signature: (I)[I
  */
 JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getStandardViewButton0
-    (JNIEnv* env, jclass cls, jint iconIndex)
+    (JNIEnv* env, jclass cls, jint iconIndex, jboolean smallIcon)
 {
     jintArray result = NULL;
+    WPARAM size = smallIcon ? (WPARAM)IDB_VIEW_SMALL_COLOR : (WPARAM)IDB_VIEW_LARGE_COLOR;
 
     // Create a toolbar
     HWND hWndToolbar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
         0, 0, 0, 0, 0,
         NULL, NULL, NULL, NULL);
 
     if (hWndToolbar != NULL) {
-        SendMessage(hWndToolbar, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);
+        SendMessage(hWndToolbar, TB_LOADIMAGES, size, (LPARAM)HINST_COMMCTRL);
 
         HIMAGELIST hImageList = (HIMAGELIST) SendMessage(hWndToolbar, TB_GETIMAGELIST, 0, 0);
 
         if (hImageList != NULL) {
             HICON hIcon = ImageList_GetIcon(hImageList, iconIndex, ILD_TRANSPARENT);
 
             if (hIcon != NULL) {
-                result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon), 16);
+                result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon));
 
                 DestroyIcon(hIcon);
             }
 
             ImageList_Destroy(hImageList);
< prev index next >