Jakub
Jakub

Reputation: 105

WPF Get Thumbnail of folder

I want to get the thumbnail image of a folder but I didn't find any way how to do it with WPF. For UWP there is a function StorageFolder.GetThumbnailAsync(). But at WPF I didn't find any solution to this.

folder icon

Upvotes: 1

Views: 1064

Answers (2)

Gellio Gao
Gellio Gao

Reputation: 843

Use Windows API Code Pack mentioned on http://stackoverflow.com/a/2994451/1360389 maybe help. Use ShellFile.FromFilePath(FilePath).Thumbnail.BitmapSource for file and use ShellFolder.FromParsingName(FolderPath).Thumbnail.BitmapSource for folder.

Upvotes: 1

HMZ
HMZ

Reputation: 3127

I was able to do it in not a very clean way via pinvoke but it's working as it should see code (use the GetIcon method):

 public static class UITools
    {
        private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
        private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;

        /// <summary>
        /// Converts a <see cref="System.Drawing.Bitmap"/> into a WPF <see cref="BitmapSource"/>.
        /// </summary>
        /// <remarks>Uses GDI to do the conversion. Hence the call to the marshalled DeleteObject.
        /// </remarks>
        /// <param name="source">The source bitmap.</param>
        /// <returns>A BitmapSource</returns>
        public static BitmapSource ToBitmapSource(this System.Drawing.Bitmap source)
        {
            BitmapSource bitSrc = null;

            var hBitmap = source.GetHbitmap();

            try
            {
                bitSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
            catch (Win32Exception)
            {
                bitSrc = null;
            }
            finally
            {
                DeleteObject(hBitmap);
            }

            return bitSrc;
        }

        public static BitmapSource GetIcon(string path,bool isDirectory)
        {
            IntPtr hIcon = GetJumboIcon(GetIconIndex(path,isDirectory));
            BitmapSource icon = null;

            using (Icon ico = (Icon)System.Drawing.Icon.FromHandle(hIcon).Clone())
            {

                icon = ico.ToBitmap().ToBitmapSource();
            }

            DestroyIcon(hIcon);

            return icon;
        }

        internal static int GetIconIndex(string pszFile,bool isDirectory)
        {
            uint attributes = FILE_ATTRIBUTE_NORMAL;
            if (isDirectory)
                attributes |= FILE_ATTRIBUTE_DIRECTORY;

            SHFILEINFO sfi = new SHFILEINFO();
            NativeMethods.SHGetFileInfo(pszFile
                , attributes //0
                , ref sfi
                , (uint)System.Runtime.InteropServices.Marshal.SizeOf(sfi)
                , (uint)(SHGFI.SysIconIndex | SHGFI.LargeIcon | SHGFI.UseFileAttributes));
            return sfi.iIcon;
        }

        // 256*256
        internal static IntPtr GetJumboIcon(int iImage)
        {
            IImageList spiml = null;
            Guid guil = new Guid(IID_IImageList); //or IID_IImageList2

            SHGetImageList(SHIL_EXTRALARGE, ref guil, ref spiml);
            IntPtr hIcon = IntPtr.Zero;
            spiml.GetIcon(iImage, ILD_TRANSPARENT | ILD_IMAGE, ref hIcon); //

            return hIcon;
        }

    }

As you can see this applies to files and folders. you can see it in action with a small tool that i made a while ago : GitHub

Upvotes: 2

Related Questions