834 * @return Whether this shell folder is marked as hidden
835 */
836 public boolean isHidden() {
837 return hasAttribute(ATTRIB_HIDDEN);
838 }
839
840
841 // Return the link location of a shell folder
842 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
843 private static native long getLinkLocation(long parentIShellFolder,
844 long relativePIDL, boolean resolve);
845
846 /**
847 * @return The shell folder linked to by this shell folder, or null
848 * if this shell folder is not a link or is a broken or invalid link
849 */
850 public ShellFolder getLinkLocation() {
851 return getLinkLocation(true);
852 }
853
854 private ShellFolder getLinkLocation(final boolean resolve) {
855 return invoke(new Callable<ShellFolder>() {
856 public ShellFolder call() {
857 if (!isLink()) {
858 return null;
859 }
860
861 ShellFolder location = null;
862 long linkLocationPIDL = getLinkLocation(getParentIShellFolder(),
863 getRelativePIDL(), resolve);
864 if (linkLocationPIDL != 0) {
865 try {
866 location =
867 Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(),
868 linkLocationPIDL);
869 } catch (InterruptedException e) {
870 // Return null
871 } catch (InternalError e) {
872 // Could be a link to a non-bindable object, such as a network connection
873 // TODO: getIShellFolder() should throw FileNotFoundException instead
874 }
875 }
876 return location;
877 }
878 });
879 }
880
881 // Parse a display name into a PIDL relative to the current IShellFolder.
951
952
953 // Icons
954
955 private static Map<Integer, Image> smallSystemImages = new HashMap<>();
956 private static Map<Integer, Image> largeSystemImages = new HashMap<>();
957 private static Map<Integer, Image> smallLinkedSystemImages = new HashMap<>();
958 private static Map<Integer, Image> largeLinkedSystemImages = new HashMap<>();
959
960 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
961 private static native long getIShellIcon(long pIShellFolder);
962
963 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
964 private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
965
966 // Return the icon of a file system shell folder in the form of an HICON
967 private static native long getIcon(String absolutePath, boolean getLargeIcon);
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 extractIcon(long parentIShellFolder, long relativePIDL,
971 boolean getLargeIcon);
972
973 // Returns an icon from the Windows system icon list in the form of an HICON
974 private static native long getSystemIcon(int iconID);
975 private static native long getIconResource(String libName, int iconID,
976 int cxDesired, int cyDesired,
977 boolean useVGAColors);
978 // Note: useVGAColors is ignored on XP and later
979
980 // Return the bits from an HICON. This has a side effect of setting
981 // the imageHash variable for efficient caching / comparing.
982 private static native int[] getIconBits(long hIcon, int iconSize);
983 // Dispose the HICON
984 private static native void disposeIcon(long hIcon);
985
986 static native int[] getStandardViewButton0(int iconIndex);
987
988 // Should be called from the COM thread
989 private long getIShellIcon() {
990 if (pIShellIcon == -1L) {
991 pIShellIcon = getIShellIcon(getIShellFolder());
1002 if (iconBits != null) {
1003 BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
1004 img.setRGB(0, 0, size, size, iconBits, 0, size);
1005 return img;
1006 }
1007 }
1008 return null;
1009 }
1010
1011
1012 /**
1013 * @return The icon image used to display this shell folder
1014 */
1015 public Image getIcon(final boolean getLargeIcon) {
1016 Image icon = getLargeIcon ? largeIcon : smallIcon;
1017 if (icon == null) {
1018 icon =
1019 invoke(new Callable<Image>() {
1020 public Image call() {
1021 Image newIcon = null;
1022 if (isFileSystem()) {
1023 long parentIShellIcon = (parent != null)
1024 ? ((Win32ShellFolder2) parent).getIShellIcon()
1025 : 0L;
1026 long relativePIDL = getRelativePIDL();
1027
1028 // These are cached per type (using the index in the system image list)
1029 int index = getIconIndex(parentIShellIcon, relativePIDL);
1030 if (index > 0) {
1031 Map<Integer, Image> imageCache;
1032 if (isLink()) {
1033 imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
1034 } else {
1035 imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
1036 }
1037 newIcon = imageCache.get(Integer.valueOf(index));
1038 if (newIcon == null) {
1039 long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
1040 newIcon = makeIcon(hIcon, getLargeIcon);
1041 disposeIcon(hIcon);
1042 if (newIcon != null) {
1043 imageCache.put(Integer.valueOf(index), newIcon);
1044 }
1045 }
1046 }
1047 }
1048
1049 if (newIcon == null) {
1050 // These are only cached per object
1051 long hIcon = extractIcon(getParentIShellFolder(),
1052 getRelativePIDL(), getLargeIcon);
1053 newIcon = makeIcon(hIcon, getLargeIcon);
1054 disposeIcon(hIcon);
1055 }
1056
1057 if (newIcon == null) {
1058 newIcon = Win32ShellFolder2.super.getIcon(getLargeIcon);
1059 }
1060 return newIcon;
1061 }
1062 });
1063 if (getLargeIcon) {
1064 largeIcon = icon;
1065 } else {
1066 smallIcon = icon;
1067 }
1068 }
1069 return icon;
1070 }
1071
1072 /**
|
834 * @return Whether this shell folder is marked as hidden
835 */
836 public boolean isHidden() {
837 return hasAttribute(ATTRIB_HIDDEN);
838 }
839
840
841 // Return the link location of a shell folder
842 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
843 private static native long getLinkLocation(long parentIShellFolder,
844 long relativePIDL, boolean resolve);
845
846 /**
847 * @return The shell folder linked to by this shell folder, or null
848 * if this shell folder is not a link or is a broken or invalid link
849 */
850 public ShellFolder getLinkLocation() {
851 return getLinkLocation(true);
852 }
853
854 private Win32ShellFolder2 getLinkLocation(final boolean resolve) {
855 return invoke(new Callable<Win32ShellFolder2>() {
856 public Win32ShellFolder2 call() {
857 if (!isLink()) {
858 return null;
859 }
860
861 Win32ShellFolder2 location = null;
862 long linkLocationPIDL = getLinkLocation(getParentIShellFolder(),
863 getRelativePIDL(), resolve);
864 if (linkLocationPIDL != 0) {
865 try {
866 location =
867 Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(),
868 linkLocationPIDL);
869 } catch (InterruptedException e) {
870 // Return null
871 } catch (InternalError e) {
872 // Could be a link to a non-bindable object, such as a network connection
873 // TODO: getIShellFolder() should throw FileNotFoundException instead
874 }
875 }
876 return location;
877 }
878 });
879 }
880
881 // Parse a display name into a PIDL relative to the current IShellFolder.
951
952
953 // Icons
954
955 private static Map<Integer, Image> smallSystemImages = new HashMap<>();
956 private static Map<Integer, Image> largeSystemImages = new HashMap<>();
957 private static Map<Integer, Image> smallLinkedSystemImages = new HashMap<>();
958 private static Map<Integer, Image> largeLinkedSystemImages = new HashMap<>();
959
960 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
961 private static native long getIShellIcon(long pIShellFolder);
962
963 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
964 private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
965
966 // Return the icon of a file system shell folder in the form of an HICON
967 private static native long getIcon(String absolutePath, boolean getLargeIcon);
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 extractIcon(long parentIShellFolder, long relativePIDL,
971 boolean getLargeIcon, boolean getDefaultIcon);
972
973 // Returns an icon from the Windows system icon list in the form of an HICON
974 private static native long getSystemIcon(int iconID);
975 private static native long getIconResource(String libName, int iconID,
976 int cxDesired, int cyDesired,
977 boolean useVGAColors);
978 // Note: useVGAColors is ignored on XP and later
979
980 // Return the bits from an HICON. This has a side effect of setting
981 // the imageHash variable for efficient caching / comparing.
982 private static native int[] getIconBits(long hIcon, int iconSize);
983 // Dispose the HICON
984 private static native void disposeIcon(long hIcon);
985
986 static native int[] getStandardViewButton0(int iconIndex);
987
988 // Should be called from the COM thread
989 private long getIShellIcon() {
990 if (pIShellIcon == -1L) {
991 pIShellIcon = getIShellIcon(getIShellFolder());
1002 if (iconBits != null) {
1003 BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
1004 img.setRGB(0, 0, size, size, iconBits, 0, size);
1005 return img;
1006 }
1007 }
1008 return null;
1009 }
1010
1011
1012 /**
1013 * @return The icon image used to display this shell folder
1014 */
1015 public Image getIcon(final boolean getLargeIcon) {
1016 Image icon = getLargeIcon ? largeIcon : smallIcon;
1017 if (icon == null) {
1018 icon =
1019 invoke(new Callable<Image>() {
1020 public Image call() {
1021 Image newIcon = null;
1022 if (isLink()) {
1023 Win32ShellFolder2 folder = getLinkLocation(false);
1024 if (folder != null && folder.isLibrary()) {
1025 return folder.getIcon(getLargeIcon);
1026 }
1027 }
1028 if (isFileSystem() || isLibrary()) {
1029 long parentIShellIcon = (parent != null)
1030 ? ((Win32ShellFolder2) parent).getIShellIcon()
1031 : 0L;
1032 long relativePIDL = getRelativePIDL();
1033
1034 // These are cached per type (using the index in the system image list)
1035 int index = getIconIndex(parentIShellIcon, relativePIDL);
1036 if (index > 0) {
1037 Map<Integer, Image> imageCache;
1038 if (isLink()) {
1039 imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
1040 } else {
1041 imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
1042 }
1043 newIcon = imageCache.get(Integer.valueOf(index));
1044 if (newIcon == null) {
1045 long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
1046 newIcon = makeIcon(hIcon, getLargeIcon);
1047 disposeIcon(hIcon);
1048 if (newIcon != null) {
1049 imageCache.put(Integer.valueOf(index), newIcon);
1050 }
1051 }
1052 }
1053 }
1054
1055 if (newIcon == null) {
1056 // These are only cached per object
1057 long hIcon = extractIcon(getParentIShellFolder(),
1058 getRelativePIDL(), getLargeIcon, false);
1059 // E_PENDING: loading can take time so get the default
1060 if(hIcon <= 0) {
1061 hIcon = extractIcon(getParentIShellFolder(),
1062 getRelativePIDL(), getLargeIcon, true);
1063 if(hIcon <= 0) {
1064 if (isDirectory()) {
1065 return getShell32Icon(4, getLargeIcon);
1066 } else {
1067 return getShell32Icon(1, getLargeIcon);
1068 }
1069 }
1070 }
1071 newIcon = makeIcon(hIcon, getLargeIcon);
1072 disposeIcon(hIcon);
1073 }
1074
1075 if (newIcon == null) {
1076 newIcon = Win32ShellFolder2.super.getIcon(getLargeIcon);
1077 }
1078 return newIcon;
1079 }
1080 });
1081 if (getLargeIcon) {
1082 largeIcon = icon;
1083 } else {
1084 smallIcon = icon;
1085 }
1086 }
1087 return icon;
1088 }
1089
1090 /**
|