< prev index next >

src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java

Print this page




 960 
 961 
 962     // Icons
 963 
 964     private static Map<Integer, Image> smallSystemImages = new HashMap<>();
 965     private static Map<Integer, Image> largeSystemImages = new HashMap<>();
 966     private static Map<Integer, Image> smallLinkedSystemImages = new HashMap<>();
 967     private static Map<Integer, Image> largeLinkedSystemImages = new HashMap<>();
 968 
 969     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 970     private static native long getIShellIcon(long pIShellFolder);
 971 
 972     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 973     private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
 974 
 975     // Return the icon of a file system shell folder in the form of an HICON
 976     private static native long getIcon(String absolutePath, boolean getLargeIcon);
 977 
 978     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 979     private static native long extractIcon(long parentIShellFolder, long relativePIDL,
 980                                            boolean getLargeIcon, boolean getDefaultIcon);
 981 
 982     // Returns an icon from the Windows system icon list in the form of an HICON
 983     private static native long getSystemIcon(int iconID);
 984     private static native long getIconResource(String libName, int iconID,
 985                                                int cxDesired, int cyDesired,
 986                                                boolean useVGAColors);
 987                                                // Note: useVGAColors is ignored on XP and later
 988 
 989     // Return the bits from an HICON.  This has a side effect of setting
 990     // the imageHash variable for efficient caching / comparing.
 991     private static native int[] getIconBits(long hIcon);
 992     // Dispose the HICON
 993     private static native void disposeIcon(long hIcon);
 994 
 995     // Get buttons from native toolbar implementation.
 996     static native int[] getStandardViewButton0(int iconIndex, boolean small);
 997 
 998     // Should be called from the COM thread
 999     private long getIShellIcon() {
1000         if (pIShellIcon == -1L) {
1001             pIShellIcon = getIShellIcon(getIShellFolder());
1002         }
1003 
1004         return pIShellIcon;
1005     }
1006 
1007     private static Image makeIcon(long hIcon, boolean getLargeIcon) {
1008         if (hIcon != 0L && hIcon != -1L) {
1009             // Get the bits.  This has the side effect of setting the imageHash value for this object.
1010             final int[] iconBits = getIconBits(hIcon);
1011             if (iconBits != null) {
1012                 // icons are always square
1013                 final int size = (int) Math.sqrt(iconBits.length);
1014                 final int baseSize = getLargeIcon ? 32 : 16;
1015                 final BufferedImage img =
1016                         new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
1017                 img.setRGB(0, 0, size, size, iconBits, 0, size);
1018                 return size == baseSize
1019                         ? img
1020                         : new MultiResolutionIconImage(baseSize, img);
1021             }
1022         }
1023         return null;
1024     }
1025 




























1026 
1027     /**
1028      * @return The icon image used to display this shell folder
1029      */
1030     public Image getIcon(final boolean getLargeIcon) {

1031         Image icon = getLargeIcon ? largeIcon : smallIcon;
1032         if (icon == null) {
1033             icon =
1034                 invoke(new Callable<Image>() {
1035                     public Image call() {
1036                         Image newIcon = null;
1037                         if (isLink()) {
1038                             Win32ShellFolder2 folder = getLinkLocation(false);
1039                             if (folder != null && folder.isLibrary()) {
1040                                 return folder.getIcon(getLargeIcon);
1041                             }
1042                         }
1043                         if (isFileSystem() || isLibrary()) {
1044                             long parentIShellIcon = (parent != null)
1045                                 ? ((Win32ShellFolder2) parent).getIShellIcon()
1046                                 : 0L;
1047                             long relativePIDL = getRelativePIDL();
1048 
1049                             // These are cached per type (using the index in the system image list)
1050                             int index = getIconIndex(parentIShellIcon, relativePIDL);
1051                             if (index > 0) {
1052                                 Map<Integer, Image> imageCache;
1053                                 if (isLink()) {
1054                                     imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
1055                                 } else {
1056                                     imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
1057                                 }
1058                                 newIcon = imageCache.get(Integer.valueOf(index));
1059                                 if (newIcon == null) {
1060                                     long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
1061                                     newIcon = makeIcon(hIcon, getLargeIcon);
1062                                     disposeIcon(hIcon);
1063                                     if (newIcon != null) {
1064                                         imageCache.put(Integer.valueOf(index), newIcon);
1065                                     }
1066                                 }
1067                             }
1068                         }
1069 
1070                         if (newIcon == null) {
1071                             // These are only cached per object
1072                             long hIcon = extractIcon(getParentIShellFolder(),
1073                                     getRelativePIDL(), getLargeIcon, false);
1074                             // E_PENDING: loading can take time so get the default
1075                             if(hIcon <= 0) {
1076                                 hIcon = extractIcon(getParentIShellFolder(),
1077                                          getRelativePIDL(), getLargeIcon, true);
1078                                 if(hIcon <= 0) {
1079                                     if (isDirectory()) {
1080                                         return getShell32Icon(4, getLargeIcon);
1081                                     } else {
1082                                         return getShell32Icon(1, getLargeIcon);
1083                                     }
1084                                 }
1085                             }
1086                             newIcon = makeIcon(hIcon, getLargeIcon);
1087                             disposeIcon(hIcon);
1088                         }
1089 
1090                         if (newIcon == null) {
1091                             newIcon = Win32ShellFolder2.super.getIcon(getLargeIcon);
1092                         }
1093                         return newIcon;
1094                     }
1095                 });
1096             if (getLargeIcon) {
1097                 largeIcon = icon;
1098             } else {
1099                 smallIcon = icon;
1100             }
1101         }
1102         return icon;
1103     }
1104 
1105     /**
1106      * Gets an icon from the Windows system icon list as an {@code Image}
1107      */
1108     static Image getSystemIcon(SystemIcon iconType) {
1109         long hIcon = getSystemIcon(iconType.getIconID());
1110         Image icon = makeIcon(hIcon, true);
1111         disposeIcon(hIcon);
1112         return icon;
1113     }
1114 
1115     /**
1116      * Gets an icon from the Windows system icon list as an {@code Image}
1117      */
1118     static Image getShell32Icon(int iconID, boolean getLargeIcon) {
1119         boolean useVGAColors = true; // Will be ignored on XP and later
1120 
1121         int size = getLargeIcon ? 32 : 16;
1122 
1123         Toolkit toolkit = Toolkit.getDefaultToolkit();
1124         String shellIconBPP = (String)toolkit.getDesktopProperty("win.icon.shellIconBPP");
1125         if (shellIconBPP != null) {
1126             useVGAColors = shellIconBPP.equals("4");
1127         }
1128 
1129         long hIcon = getIconResource("shell32.dll", iconID, size, size, useVGAColors);
1130         if (hIcon != 0) {
1131             Image icon = makeIcon(hIcon, getLargeIcon);
1132             disposeIcon(hIcon);
1133             return icon;
1134         }
1135         return null;
1136     }
1137 
1138     /**
1139      * Returns the canonical form of this abstract pathname.  Equivalent to
1140      * <code>new&nbsp;Win32ShellFolder2(getParentFile(), this.{@link java.io.File#getCanonicalPath}())</code>.
1141      *
1142      * @see java.io.File#getCanonicalFile
1143      */
1144     public File getCanonicalFile() throws IOException {
1145         return this;
1146     }
1147 
1148     /*
1149      * Indicates whether this is a special folder (includes My Documents)
1150      */
1151     public boolean isSpecial() {




 960 
 961 
 962     // Icons
 963 
 964     private static Map<Integer, Image> smallSystemImages = new HashMap<>();
 965     private static Map<Integer, Image> largeSystemImages = new HashMap<>();
 966     private static Map<Integer, Image> smallLinkedSystemImages = new HashMap<>();
 967     private static Map<Integer, Image> largeLinkedSystemImages = new HashMap<>();
 968 
 969     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 970     private static native long getIShellIcon(long pIShellFolder);
 971 
 972     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 973     private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
 974 
 975     // Return the icon of a file system shell folder in the form of an HICON
 976     private static native long getIcon(String absolutePath, boolean getLargeIcon);
 977 
 978     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 979     private static native long extractIcon(long parentIShellFolder, long relativePIDL,
 980                                            int size, boolean getDefaultIcon);
 981 
 982     // Returns an icon from the Windows system icon list in the form of an HICON
 983     private static native long getSystemIcon(int iconID);
 984     private static native long getIconResource(String libName, int iconID,
 985                                                int cxDesired, int cyDesired,
 986                                                boolean useVGAColors);
 987                                                // Note: useVGAColors is ignored on XP and later
 988 
 989     // Return the bits from an HICON.  This has a side effect of setting
 990     // the imageHash variable for efficient caching / comparing.
 991     private static native int[] getIconBits(long hIcon);
 992     // Dispose the HICON
 993     private static native void disposeIcon(long hIcon);
 994 
 995     // Get buttons from native toolbar implementation.
 996     static native int[] getStandardViewButton0(int iconIndex, boolean small);
 997 
 998     // Should be called from the COM thread
 999     private long getIShellIcon() {
1000         if (pIShellIcon == -1L) {
1001             pIShellIcon = getIShellIcon(getIShellFolder());
1002         }
1003 
1004         return pIShellIcon;
1005     }
1006 
1007     private static Image makeIcon(long hIcon, int bsize) {
1008         if (hIcon != 0L && hIcon != -1L) {
1009             // Get the bits.  This has the side effect of setting the imageHash value for this object.
1010             final int[] iconBits = getIconBits(hIcon);
1011             if (iconBits != null) {
1012                 // icons are always square
1013                 final int size = (int) Math.sqrt(iconBits.length);

1014                 final BufferedImage img =
1015                         new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
1016                 img.setRGB(0, 0, size, size, iconBits, 0, size);
1017                 return size == bsize
1018                         ? img
1019                         : new MultiResolutionIconImage(bsize, img);
1020             }
1021         }
1022         return null;
1023     }
1024 
1025     public Image getIcon(int size) {
1026         return invoke(() -> {
1027             Image newIcon = null;
1028             if (isLink()) {
1029                 Win32ShellFolder2 folder = getLinkLocation(false);
1030                 if (folder != null && folder.isLibrary()) {
1031                     return folder.getIcon(size);
1032                 }
1033             }
1034             long hIcon = extractIcon(getParentIShellFolder(),
1035                     getRelativePIDL(), size, false);
1036             // E_PENDING: loading can take time so get the default
1037             if(hIcon <= 0) {
1038                 hIcon = extractIcon(getParentIShellFolder(),
1039                         getRelativePIDL(), size, true);
1040                 if(hIcon <= 0) {
1041                     if (isDirectory()) {
1042                         return getShell32Icon(4, size);
1043                     } else {
1044                         return getShell32Icon(1, size);
1045                     }
1046                 }
1047             }
1048             newIcon = makeIcon(hIcon, size);
1049             disposeIcon(hIcon);
1050             return newIcon;
1051         });
1052     }
1053 
1054     /**
1055      * @return The icon image used to display this shell folder
1056      */
1057     public Image getIcon(final boolean getLargeIcon) {
1058         int size = getLargeIcon ? 32 : 16;
1059         Image icon = getLargeIcon ? largeIcon : smallIcon;
1060         if (icon == null) {
1061             icon =
1062                 invoke(new Callable<Image>() {
1063                     public Image call() {
1064                         Image newIcon = null;
1065                         if (isLink()) {
1066                             Win32ShellFolder2 folder = getLinkLocation(false);
1067                             if (folder != null && folder.isLibrary()) {
1068                                 return folder.getIcon(getLargeIcon);
1069                             }
1070                         }
1071                         if (isFileSystem() || isLibrary()) {
1072                             long parentIShellIcon = (parent != null)
1073                                 ? ((Win32ShellFolder2) parent).getIShellIcon()
1074                                 : 0L;
1075                             long relativePIDL = getRelativePIDL();
1076 
1077                             // These are cached per type (using the index in the system image list)
1078                             int index = getIconIndex(parentIShellIcon, relativePIDL);
1079                             if (index > 0) {
1080                                 Map<Integer, Image> imageCache;
1081                                 if (isLink()) {
1082                                     imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
1083                                 } else {
1084                                     imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
1085                                 }
1086                                 newIcon = imageCache.get(Integer.valueOf(index));
1087                                 if (newIcon == null) {
1088                                     long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
1089                                     newIcon = makeIcon(hIcon, size);
1090                                     disposeIcon(hIcon);
1091                                     if (newIcon != null) {
1092                                         imageCache.put(Integer.valueOf(index), newIcon);
1093                                     }
1094                                 }
1095                             }
1096                         }
1097 
1098                         if (newIcon == null) {
1099                             // These are only cached per object
1100                             long hIcon = extractIcon(getParentIShellFolder(),
1101                                     getRelativePIDL(), size, false);
1102                             // E_PENDING: loading can take time so get the default
1103                             if(hIcon <= 0) {
1104                                 hIcon = extractIcon(getParentIShellFolder(),
1105                                          getRelativePIDL(), size, true);
1106                                 if(hIcon <= 0) {
1107                                     if (isDirectory()) {
1108                                         return getShell32Icon(4, size);
1109                                     } else {
1110                                         return getShell32Icon(1, size);
1111                                     }
1112                                 }
1113                             }
1114                             newIcon = makeIcon(hIcon, size);
1115                             disposeIcon(hIcon);
1116                         }
1117 



1118                         return newIcon;
1119                     }
1120                 });





1121         }
1122         return icon;
1123     }
1124 
1125     /**
1126      * Gets an icon from the Windows system icon list as an {@code Image}
1127      */
1128     static Image getSystemIcon(SystemIcon iconType) {
1129         long hIcon = getSystemIcon(iconType.getIconID());
1130         Image icon = makeIcon(hIcon, 32);
1131         disposeIcon(hIcon);
1132         return icon;
1133     }
1134 
1135     /**
1136      * Gets an icon from the Windows system icon list as an {@code Image}
1137      */
1138     static Image getShell32Icon(int iconID, int size) {
1139         boolean useVGAColors = true; // Will be ignored on XP and later
1140 


1141         Toolkit toolkit = Toolkit.getDefaultToolkit();
1142         String shellIconBPP = (String)toolkit.getDesktopProperty("win.icon.shellIconBPP");
1143         if (shellIconBPP != null) {
1144             useVGAColors = shellIconBPP.equals("4");
1145         }
1146 
1147         long hIcon = getIconResource("shell32.dll", iconID, size, size, useVGAColors);
1148         if (hIcon != 0) {
1149             Image icon = makeIcon(hIcon, size);
1150             disposeIcon(hIcon);
1151             return icon;
1152         }
1153         return null;
1154     }
1155 
1156     /**
1157      * Returns the canonical form of this abstract pathname.  Equivalent to
1158      * <code>new&nbsp;Win32ShellFolder2(getParentFile(), this.{@link java.io.File#getCanonicalPath}())</code>.
1159      *
1160      * @see java.io.File#getCanonicalFile
1161      */
1162     public File getCanonicalFile() throws IOException {
1163         return this;
1164     }
1165 
1166     /*
1167      * Indicates whether this is a special folder (includes My Documents)
1168      */
1169     public boolean isSpecial() {


< prev index next >