939
940
941 // Icons
942
943 private static Map<Integer, Image> smallSystemImages = new HashMap<>();
944 private static Map<Integer, Image> largeSystemImages = new HashMap<>();
945 private static Map<Integer, Image> smallLinkedSystemImages = new HashMap<>();
946 private static Map<Integer, Image> largeLinkedSystemImages = new HashMap<>();
947
948 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
949 private static native long getIShellIcon(long pIShellFolder);
950
951 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
952 private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
953
954 // Return the icon of a file system shell folder in the form of an HICON
955 private static native long getIcon(String absolutePath, boolean getLargeIcon);
956
957 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
958 private static native long extractIcon(long parentIShellFolder, long relativePIDL,
959 boolean getLargeIcon);
960
961 // Returns an icon from the Windows system icon list in the form of an HICON
962 private static native long getSystemIcon(int iconID);
963 private static native long getIconResource(String libName, int iconID,
964 int cxDesired, int cyDesired,
965 boolean useVGAColors);
966 // Note: useVGAColors is ignored on XP and later
967
968 // Return the bits from an HICON. This has a side effect of setting
969 // the imageHash variable for efficient caching / comparing.
970 private static native int[] getIconBits(long hIcon, int iconSize);
971 // Dispose the HICON
972 private static native void disposeIcon(long hIcon);
973
974 static native int[] getStandardViewButton0(int iconIndex);
975
976 // Should be called from the COM thread
977 private long getIShellIcon() {
978 if (pIShellIcon == -1L) {
979 pIShellIcon = getIShellIcon(getIShellFolder());
990 if (iconBits != null) {
991 BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
992 img.setRGB(0, 0, size, size, iconBits, 0, size);
993 return img;
994 }
995 }
996 return null;
997 }
998
999
1000 /**
1001 * @return The icon image used to display this shell folder
1002 */
1003 public Image getIcon(final boolean getLargeIcon) {
1004 Image icon = getLargeIcon ? largeIcon : smallIcon;
1005 if (icon == null) {
1006 icon =
1007 invoke(new Callable<Image>() {
1008 public Image call() {
1009 Image newIcon = null;
1010 if (isFileSystem()) {
1011 long parentIShellIcon = (parent != null)
1012 ? ((Win32ShellFolder2) parent).getIShellIcon()
1013 : 0L;
1014 long relativePIDL = getRelativePIDL();
1015
1016 // These are cached per type (using the index in the system image list)
1017 int index = getIconIndex(parentIShellIcon, relativePIDL);
1018 if (index > 0) {
1019 Map<Integer, Image> imageCache;
1020 if (isLink()) {
1021 imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
1022 } else {
1023 imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
1024 }
1025 newIcon = imageCache.get(Integer.valueOf(index));
1026 if (newIcon == null) {
1027 long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
1028 newIcon = makeIcon(hIcon, getLargeIcon);
1029 disposeIcon(hIcon);
1030 if (newIcon != null) {
1031 imageCache.put(Integer.valueOf(index), newIcon);
1032 }
1033 }
1034 }
1035 }
1036
1037 if (newIcon == null) {
1038 // These are only cached per object
1039 long hIcon = extractIcon(getParentIShellFolder(),
1040 getRelativePIDL(), getLargeIcon);
1041 newIcon = makeIcon(hIcon, getLargeIcon);
1042 disposeIcon(hIcon);
1043 }
1044
1045 if (newIcon == null) {
1046 newIcon = Win32ShellFolder2.super.getIcon(getLargeIcon);
1047 }
1048 return newIcon;
1049 }
1050 });
1051 if (getLargeIcon) {
1052 largeIcon = icon;
1053 } else {
1054 smallIcon = icon;
1055 }
1056 }
1057 return icon;
1058 }
1059
1060 /**
|
939
940
941 // Icons
942
943 private static Map<Integer, Image> smallSystemImages = new HashMap<>();
944 private static Map<Integer, Image> largeSystemImages = new HashMap<>();
945 private static Map<Integer, Image> smallLinkedSystemImages = new HashMap<>();
946 private static Map<Integer, Image> largeLinkedSystemImages = new HashMap<>();
947
948 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
949 private static native long getIShellIcon(long pIShellFolder);
950
951 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
952 private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
953
954 // Return the icon of a file system shell folder in the form of an HICON
955 private static native long getIcon(String absolutePath, boolean getLargeIcon);
956
957 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
958 private static native long extractIcon(long parentIShellFolder, long relativePIDL,
959 boolean getLargeIcon, boolean getDefaultIcon);
960
961 // Returns an icon from the Windows system icon list in the form of an HICON
962 private static native long getSystemIcon(int iconID);
963 private static native long getIconResource(String libName, int iconID,
964 int cxDesired, int cyDesired,
965 boolean useVGAColors);
966 // Note: useVGAColors is ignored on XP and later
967
968 // Return the bits from an HICON. This has a side effect of setting
969 // the imageHash variable for efficient caching / comparing.
970 private static native int[] getIconBits(long hIcon, int iconSize);
971 // Dispose the HICON
972 private static native void disposeIcon(long hIcon);
973
974 static native int[] getStandardViewButton0(int iconIndex);
975
976 // Should be called from the COM thread
977 private long getIShellIcon() {
978 if (pIShellIcon == -1L) {
979 pIShellIcon = getIShellIcon(getIShellFolder());
990 if (iconBits != null) {
991 BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
992 img.setRGB(0, 0, size, size, iconBits, 0, size);
993 return img;
994 }
995 }
996 return null;
997 }
998
999
1000 /**
1001 * @return The icon image used to display this shell folder
1002 */
1003 public Image getIcon(final boolean getLargeIcon) {
1004 Image icon = getLargeIcon ? largeIcon : smallIcon;
1005 if (icon == null) {
1006 icon =
1007 invoke(new Callable<Image>() {
1008 public Image call() {
1009 Image newIcon = null;
1010 if (isLink()) {
1011 ShellFolder folder = getLinkLocation();
1012 if (folder != null && "Library".equals(
1013 folder.getFolderType())) {
1014 return folder.getIcon(getLargeIcon);
1015 }
1016 }
1017 if (isFileSystem() || "Library".equals(getFolderType())) {
1018 long parentIShellIcon = (parent != null)
1019 ? ((Win32ShellFolder2) parent).getIShellIcon()
1020 : 0L;
1021 long relativePIDL = getRelativePIDL();
1022
1023 // These are cached per type (using the index in the system image list)
1024 int index = getIconIndex(parentIShellIcon, relativePIDL);
1025 if (index > 0) {
1026 Map<Integer, Image> imageCache;
1027 if (isLink()) {
1028 imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
1029 } else {
1030 imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
1031 }
1032 newIcon = imageCache.get(Integer.valueOf(index));
1033 if (newIcon == null) {
1034 long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
1035 newIcon = makeIcon(hIcon, getLargeIcon);
1036 disposeIcon(hIcon);
1037 if (newIcon != null) {
1038 imageCache.put(Integer.valueOf(index), newIcon);
1039 }
1040 }
1041 }
1042 }
1043
1044 if (newIcon == null) {
1045 // These are only cached per object
1046 long hIcon = extractIcon(getParentIShellFolder(),
1047 getRelativePIDL(), getLargeIcon, false);
1048 // E_PENDING: loading can take time so get the default
1049 if(hIcon <= 0) {
1050 hIcon = extractIcon(getParentIShellFolder(),
1051 getRelativePIDL(), getLargeIcon, true);
1052 if(hIcon <= 0) {
1053 if (isDirectory()) {
1054 return getShell32Icon(4, getLargeIcon);
1055 } else {
1056 return getShell32Icon(1, getLargeIcon);
1057 }
1058 }
1059 }
1060 newIcon = makeIcon(hIcon, getLargeIcon);
1061 disposeIcon(hIcon);
1062 }
1063
1064 if (newIcon == null) {
1065 newIcon = Win32ShellFolder2.super.getIcon(getLargeIcon);
1066 }
1067 return newIcon;
1068 }
1069 });
1070 if (getLargeIcon) {
1071 largeIcon = icon;
1072 } else {
1073 smallIcon = icon;
1074 }
1075 }
1076 return icon;
1077 }
1078
1079 /**
|