source: branches/eraser6/Util/File.cs @ 230

Revision 230, 13.3 KB checked in by lowjoel, 6 years ago (diff)

Use the PathCompactPathEx? function to code a GetCompactPath? function for use with the progress dialog.

Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using System.Runtime.InteropServices;
6using System.Windows.Forms;
7using System.Drawing;
8
9namespace Eraser.Util
10{
11    using HICON = IntPtr;
12    using HIMAGELIST = IntPtr;
13
14    public class File
15    {
16        /// <summary>
17        /// Uses SHGetFileInfo to retrieve the description for the given file,
18        /// folder or drive.
19        /// </summary>
20        /// <param name="path">A string that contains the path and file name for
21        /// the file in question. Both absolute and relative paths are valid.</param>
22        /// <returns>A string containing the description</returns>
23        public static string GetFileDescription(string path)
24        {
25            SHFILEINFO shfi = new SHFILEINFO();
26            SHGetFileInfo(path, 0, ref shfi, Marshal.SizeOf(shfi),
27                SHGetFileInfoFlags.SHGFI_DISPLAYNAME);
28            return shfi.szDisplayName;
29        }
30
31        /// <summary>
32        /// Uses SHGetFileInfo to retrieve the icon for the given file, folder or
33        /// drive.
34        /// </summary>
35        /// <param name="path">A string that contains the path and file name for
36        /// the file in question. Both absolute and relative paths are valid.</param>
37        /// <returns>An Icon object containing the bitmap</returns>
38        public static Icon GetFileIcon(string path)
39        {
40            SHFILEINFO shfi = new SHFILEINFO();
41            SHGetFileInfo(path, 0, ref shfi, Marshal.SizeOf(shfi),
42                SHGetFileInfoFlags.SHGFI_SMALLICON | SHGetFileInfoFlags.SHGFI_ICON);
43            return Icon.FromHandle(shfi.hIcon);
44        }
45
46        public static string GetCompactPath(string longPath, int newWidth, Font drawFont)
47        {
48            using (Control ctrl = new Control())
49            {
50                //First check if the source string is too long.
51                Graphics g = ctrl.CreateGraphics();
52                int width = g.MeasureString(longPath, drawFont).ToSize().Width;
53                if (width <= newWidth)
54                    return longPath;
55
56                //It is, shorten it.
57                int aveCharWidth = width / longPath.Length;
58                int charCount = newWidth / aveCharWidth;
59                StringBuilder builder = new StringBuilder();
60                builder.Append(longPath);
61                builder.EnsureCapacity(charCount);
62
63                while (g.MeasureString(builder.ToString(), drawFont).Width > newWidth)
64                {
65                    if (PathCompactPathEx(builder, longPath, (UIntPtr)(--charCount),
66                        (UIntPtr)0) == UIntPtr.Zero)
67                    {
68                        return string.Empty;
69                    }
70                }
71
72                return builder.ToString();
73            }
74        }
75
76        /// <summary>
77        /// Truncates a path to fit within a certain number of characters by
78        /// replacing path components with ellipses.
79        /// </summary>
80        /// <param name="pszOut">[out] The address of the string that has been altered.</param>
81        /// <param name="pszSrc">[in] A pointer to a null-terminated string of maximum
82        /// length MAX_PATH that contains the path to be altered.</param>
83        /// <param name="cchMax">[in] The maximum number of characters to be
84        /// contained in the new string, including the terminating NULL character.
85        /// For example, if cchMax = 8, the resulting string can contain a maximum
86        /// of 7 characters plus the terminating NULL character.</param>
87        /// <param name="dwFlags">Reserved.</param>
88        /// <returns>Returns TRUE if successful, or FALSE otherwise.</returns>
89        [DllImport("Shlwapi.dll")]
90        private static extern UIntPtr PathCompactPathEx(
91            StringBuilder pszOut, string pszSrc, UIntPtr cchMax, UIntPtr dwFlags);
92
93        /// <summary>
94        /// Retrieves information about an object in the file system, such as a
95        /// file, folder, directory, or drive root.
96        /// </summary>
97        /// <param name="path">[in] A pointer to a null-terminated string of maximum
98        /// length MAX_PATH that contains the path and file name. Both absolute
99        /// and relative paths are valid.
100        ///
101        /// If the uFlags parameter includes the SHGFI_PIDL flag, this parameter
102        /// must be the address of an ITEMIDLIST (PIDL) structure that contains
103        /// the list of item identifiers that uniquely identifies the file within
104        /// the Shell's namespace. The pointer to an item identifier list (PIDL)
105        /// must be a fully qualified PIDL. Relative PIDLs are not allowed.
106        ///
107        /// If the uFlags parameter includes the SHGFI_USEFILEATTRIBUTES flag,
108        /// this parameter does not have to be a valid file name. The function
109        /// will proceed as if the file exists with the specified name and with
110        /// the file attributes passed in the dwFileAttributes parameter. This
111        /// allows you to obtain information about a file type by passing just
112        /// the extension for pszPath and passing FILE_ATTRIBUTE_NORMAL in
113        /// dwFileAttributes.
114        ///
115        /// This string can use either short (the 8.3 form) or long file names.</param>
116        /// <param name="fileAttributes">[in] A combination of one or more file
117        /// attribute flags (FILE_ATTRIBUTE_ values as defined in Winnt.h). If
118        /// uFlags does not include the SHGFI_USEFILEATTRIBUTES flag, this
119        /// parameter is ignored.</param>
120        /// <param name="psfi">[out] The address of a SHFILEINFO structure to
121        /// receive the file information.</param>
122        /// <param name="cbFileInfo">[in] The size, in bytes, of the SHFILEINFO
123        /// structure pointed to by the psfi parameter.</param>
124        /// <param name="uFlags">[in] The flags that specify the file information to retrieve.
125        /// This parameter can be a combination of the values in SHGetFileInfoFlags</param>
126        /// <returns>Returns a value whose meaning depends on the uFlags parameter.
127        ///
128        /// If uFlags does not contain SHGFI_EXETYPE or SHGFI_SYSICONINDEX, the return
129        /// value is nonzero if successful, or zero otherwise.
130        ///
131        /// If uFlags contains the SHGFI_EXETYPE flag, the return value specifies
132        /// the type of the executable file. It will be one of the following values.
133        ///     0                                               Nonexecutable file or an error condition.
134        ///     LOWORD = NE or PE and HIWORD = Windows version  Microsoft Windows application.
135        ///     LOWORD = MZ and HIWORD = 0                      Windows 95, Windows 98: Microsoft MS-DOS .exe, .com, or .bat file
136        ///                                                     Microsoft Windows NT, Windows 2000, Windows XP: MS-DOS .exe or .com file
137        ///     LOWORD = PE and HIWORD = 0                      Windows 95, Windows 98: Microsoft Win32 console application
138        ///                                                     Windows NT, Windows 2000, Windows XP: Win32 console application or .bat file
139        /// </returns>
140        [DllImport("Shell32.dll")]
141        private static extern IntPtr SHGetFileInfo(string path, uint fileAttributes,
142            ref SHFILEINFO psfi, int fileInfo, SHGetFileInfoFlags flags);
143
144        enum SHGetFileInfoFlags
145        {
146            /// <summary>
147            /// Retrieve the handle to the icon that represents the file and the
148            /// index of the icon within the system image list. The handle is
149            /// copied to the hIcon member of the structure specified by psfi,
150            /// and the index is copied to the iIcon member.
151            /// </summary>
152            SHGFI_ICON              = 0x000000100,
153
154            /// <summary>
155            /// Retrieve the display name for the file. The name is copied to the
156            /// szDisplayName member of the structure specified in psfi. The returned
157            /// display name uses the long file name, if there is one, rather than
158            /// the 8.3 form of the file name.
159            /// </summary>
160            SHGFI_DISPLAYNAME       = 0x000000200,
161
162            /// <summary>
163            /// Retrieve the string that describes the file's type. The string
164            /// is copied to the szTypeName member of the structure specified in
165            /// psfi.
166            /// </summary>
167            SHGFI_TYPENAME          = 0x000000400,
168
169            /// <summary>
170            /// Retrieve the item attributes. The attributes are copied to the
171            /// dwAttributes member of the structure specified in the psfi parameter.
172            /// These are the same attributes that are obtained from
173            /// IShellFolder::GetAttributesOf.
174            /// </summary>
175            SHGFI_ATTRIBUTES        = 0x000000800,
176
177            /// <summary>
178            /// Retrieve the name of the file that contains the icon representing
179            /// the file specified by pszPath, as returned by the
180            /// IExtractIcon::GetIconLocation method of the file's icon handler.
181            /// Also retrieve the icon index within that file. The name of the
182            /// file containing the icon is copied to the szDisplayName member
183            /// of the structure specified by psfi. The icon's index is copied to
184            /// that structure's iIcon member.
185            /// </summary>
186            SHGFI_ICONLOCATION      = 0x000001000,
187
188            /// <summary>
189            /// Retrieve the type of the executable file if pszPath identifies an
190            /// executable file. The information is packed into the return value.
191            /// This flag cannot be specified with any other flags.
192            /// </summary>
193            SHGFI_EXETYPE           = 0x000002000,
194
195            /// <summary>
196            /// Retrieve the index of a system image list icon. If successful,
197            /// the index is copied to the iIcon member of psfi. The return value
198            /// is a handle to the system image list. Only those images whose
199            /// indices are successfully copied to iIcon are valid. Attempting
200            /// to access other images in the system image list will result in
201            /// undefined behavior.
202            /// </summary>
203            SHGFI_SYSICONINDEX      = 0x000004000,
204           
205            /// <summary>
206            /// Modify SHGFI_ICON, causing the function to add the link overlay
207            /// to the file's icon. The SHGFI_ICON flag must also be set.
208            /// </summary>
209            SHGFI_LINKOVERLAY       = 0x000008000,
210
211            /// <summary>
212            /// Modify SHGFI_ICON, causing the function to blend the file's icon
213            /// with the system highlight color. The SHGFI_ICON flag must also
214            /// be set.
215            /// </summary>
216            SHGFI_SELECTED          = 0x000010000,
217
218            /// <summary>
219            /// Modify SHGFI_ATTRIBUTES to indicate that the dwAttributes member
220            /// of the SHFILEINFO structure at psfi contains the specific attributes
221            /// that are desired. These attributes are passed to IShellFolder::GetAttributesOf.
222            /// If this flag is not specified, 0xFFFFFFFF is passed to
223            /// IShellFolder::GetAttributesOf, requesting all attributes. This flag
224            /// cannot be specified with the SHGFI_ICON flag.
225            /// </summary>
226            SHGFI_ATTR_SPECIFIED    = 0x000020000,
227
228            /// <summary>
229            /// Modify SHGFI_ICON, causing the function to retrieve the file's
230            /// large icon. The SHGFI_ICON flag must also be set.
231            /// </summary>
232            SHGFI_LARGEICON         = 0x000000000,
233
234            /// <summary>
235            /// Modify SHGFI_ICON, causing the function to retrieve the file's
236            /// small icon. Also used to modify SHGFI_SYSICONINDEX, causing the
237            /// function to return the handle to the system image list that
238            /// contains small icon images. The SHGFI_ICON and/or
239            /// SHGFI_SYSICONINDEX flag must also be set.
240            /// </summary>
241            SHGFI_SMALLICON         = 0x000000001,
242
243            /// <summary>
244            /// Modify SHGFI_ICON, causing the function to retrieve the file's
245            /// open icon. Also used to modify SHGFI_SYSICONINDEX, causing the
246            /// function to return the handle to the system image list that
247            /// contains the file's small open icon. A container object displays
248            /// an open icon to indicate that the container is open. The SHGFI_ICON
249            /// and/or SHGFI_SYSICONINDEX flag must also be set.
250            /// </summary>
251            SHGFI_OPENICON          = 0x000000002,
252
253            /// <summary>
254            /// Modify SHGFI_ICON, causing the function to retrieve a Shell-sized
255            /// icon. If this flag is not specified the function sizes the icon
256            /// according to the system metric values. The SHGFI_ICON flag must
257            /// also be set.
258            /// </summary>
259            SHGFI_SHELLICONSIZE     = 0x000000004,
260           
261            /// <summary>
262            /// Indicate that pszPath is the address of an ITEMIDLIST structure
263            /// rather than a path name.
264            /// </summary>
265            SHGFI_PIDL              = 0x000000008,
266
267            /// <summary>
268            /// Indicates that the function should not attempt to access the file
269            /// specified by pszPath. Rather, it should act as if the file specified
270            /// by pszPath exists with the file attributes passed in dwFileAttributes.
271            /// This flag cannot be combined with the SHGFI_ATTRIBUTES, SHGFI_EXETYPE,
272            /// or SHGFI_PIDL flags.
273            /// </summary>
274            SHGFI_USEFILEATTRIBUTES = 0x000000010,
275
276            /// <summary>
277            /// Version 5.0. Apply the appropriate overlays to the file's icon.
278            /// The SHGFI_ICON flag must also be set.
279            /// </summary>
280            SHGFI_ADDOVERLAYS       = 0x000000020,
281           
282            /// <summary>
283            /// Version 5.0. Return the index of the overlay icon. The value of
284            /// the overlay index is returned in the upper eight bits of the iIcon
285            /// member of the structure specified by psfi. This flag requires that
286            /// the SHGFI_ICON be set as well.
287            /// </summary>
288            SHGFI_OVERLAYINDEX      = 0x000000040
289        }
290
291        private struct SHFILEINFO
292        {
293            /// <summary>
294            /// A handle to the icon that represents the file. You are responsible
295            /// for destroying this handle with DestroyIcon when you no longer need it.
296            /// </summary>
297            public HICON hIcon;
298
299            /// <summary>
300            /// The index of the icon image within the system image list.
301            /// </summary>
302            public int iIcon;
303
304            /// <summary>
305            /// An array of values that indicates the attributes of the file object.
306            /// For information about these values, see the IShellFolder::GetAttributesOf
307            /// method.
308            /// </summary>
309            public uint dwAttributes;
310
311            /// <summary>
312            /// A string that contains the name of the file as it appears in the
313            /// Microsoft Windows Shell, or the path and file name of the file
314            /// that contains the icon representing the file.
315            /// </summary>
316            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
317            public string szDisplayName;
318
319            /// <summary>
320            /// A string that describes the type of file.
321            /// </summary>
322            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
323            public string szTypeName;
324        }
325    }
326}
Note: See TracBrowser for help on using the repository browser.