2018年1月30日 星期二

C#利用WIN32API(shell32) 不完整模仿檔案總管

先製作一個WIIN32 API CLASS
將內建的圖形檔讀進來

sing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
//call win32 dll
using System.Runtime.InteropServices;

namespace Win32API
{
   public class Shell32
    {
        public Shell32() { }

        public enum IconSize
        {
            Small,
            Large
        }

        public enum SHGFI
        {
            SHGFI_ICON = 0x100,
            SHGFI_LARGEICON = 0,
            SHGFI_OPENICON = 2,
            SHGFI_SMALLICON = 1
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.LPStr)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string szTypeName;

            public SHFILEINFO(bool b)
            {
                this.hIcon = IntPtr.Zero;
                this.iIcon = 0;
                this.dwAttributes = 0;
                this.szDisplayName = "";
                this.szTypeName = "";
            }
        }

     
        [DllImport("Shell32.dll")]
        private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbfileInfo, SHGFI uFlags);
       
        public static Icon GetFolderIcon(string strPath, bool isOpen)
        //public static Icon GetFolderIcon(string strPath, SHGFI shgfi)
        {
            SHGFI shgfi;
            SHFILEINFO structure = new SHFILEINFO(true);
            int num = Marshal.SizeOf(structure);
            if (isOpen)
            {
                shgfi = SHGFI.SHGFI_ICON | SHGFI.SHGFI_OPENICON | SHGFI.SHGFI_LARGEICON;
            }
            else
            {
                shgfi = SHGFI.SHGFI_LARGEICON | SHGFI.SHGFI_ICON;
            }
            SHGetFileInfo(strPath, 0x100, out structure, (uint)num, shgfi);
            return Icon.FromHandle(structure.hIcon);
        }

        [DllImport("Shell32.dll", CharSet = CharSet.Auto)]
        public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons);

        public static Icon GetShellIcon(int index, IconSize iconSize)
        {
            if ((index > 0xed) || (index < 0))
            {
                return null;
            }

            IntPtr[] phiconLarge = new IntPtr[1];
            IntPtr[] phiconSmall = new IntPtr[1];
            uint num = ExtractIconEx(Environment.SystemDirectory + @"\shell32.dll", index, phiconLarge, phiconSmall, 1);
            switch (iconSize)
            {
                case IconSize.Small:
                    return Icon.FromHandle(phiconSmall[0]);

                case IconSize.Large:
                    return Icon.FromHandle(phiconLarge[0]);
            }
            return null;
        } 

    }
}


  1. 將 SplitContainer 控制項加入至表單,並將 Dock 屬性設定為 Fill。
  2. 將名為 imageList1 的 ImageList 加入至表單,並使用 [屬性] 視窗加入兩個影像:資料夾影像和文件影像 (依此順序)。
  3. 將名為 treeview1 的 TreeView 控制項加入至表單,並將它放置在 SplitContainer 控制項的左邊。 在 treeView1 的 [屬性] 視窗中,執行下列操作:
    1. 將 Dock 屬性設為 Fill。
    2. 將 ImageList 屬性設為 imagelist1.
  4. 將名為 listView1 的 ListView 控制項加入至表單,並將它放置在 SplitContainer 控制項的右邊。 在 listview1 的 [屬性] 視窗中,執行下列操作:
    1. 將 Dock 屬性設為 Fill
    2. 將 View 屬性設定為 Details。
    3. 按一下 Columns 屬性中的省略符號 (VisualStudioEllipsesButton 螢幕擷取畫面),藉此開啟 [ColumnHeader 集合編輯器]。 加入三個資料行,並將它們的 Text 屬性分別設定為 NameType 和 Last Modified 按一下 [確定] 以關閉對話方塊。(看您要顯示的格式製作)
    4. 將 SmallImageList 屬性設定為 imageList1.
  5. 實作程式碼,以節點和子節點填入 TreeView。 將此程式碼加入至 Form1 類別。
public partial class Form1 : Form
    {
        TreeNode newSelected;
        int nIndex = 0;
        public Form1()
        {
            InitializeComponent();
            this.treeView1.NodeMouseClick +=
    new TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseClick);
            this.listView1.ItemSelectionChanged +=
 new ListViewItemSelectionChangedEventHandler(listView1_SelectedIndexChanged);
            PopulateTreeView();           
        }
        private void PopulateTreeView()
        {
            TreeNode rootNode;

            DirectoryInfo info = new DirectoryInfo(@"D:\TEST\");
            if (info.Exists)
            {
                rootNode = new TreeNode(info.Name);
                rootNode.Tag = info;
                GetDirectories(info.GetDirectories(), rootNode);
                treeView1.Nodes.Add(rootNode);

            }
        }
       


        private void GetDirectories(DirectoryInfo[] subDirs,
   TreeNode nodeToAddTo)
        {
            TreeNode aNode;
            DirectoryInfo[] subSubDirs;
            foreach (DirectoryInfo subDir in subDirs)
            {
                aNode = new TreeNode(subDir.Name, 0, 0);
                aNode.Tag = subDir;
                aNode.ImageKey = "folder";
                subSubDirs = subDir.GetDirectories();
                if (subSubDirs.Length != 0)
                {
                    GetDirectories(subSubDirs, aNode);
                }
                nodeToAddTo.Nodes.Add(aNode);
            }
        }
        void treeView1_NodeMouseClick(object sender,
    TreeNodeMouseClickEventArgs e)
        {
           newSelected = e.Node;
            listView1.Items.Clear();
            DirectoryInfo nodeDirInfo = (DirectoryInfo)newSelected.Tag;
            ListViewItem.ListViewSubItem[] subItems;
            ListViewItem item = null;

            foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())
            {
                item = new ListViewItem(dir.Name, 0);
                subItems = new ListViewItem.ListViewSubItem[]
                  {new ListViewItem.ListViewSubItem(item, "Directory"), 
                   new ListViewItem.ListViewSubItem(item, 
dir.LastAccessTime.ToShortDateString())};
                //item.
                item.SubItems.AddRange(subItems);
                listView1.Items.Add(item);
            }
            listView1.SmallImageList = imageList1;
            listView1.LargeImageList = imageList1;
            foreach (FileInfo file in nodeDirInfo.GetFiles())
            {
                item = new ListViewItem(file.Name, 1);
                subItems = new ListViewItem.ListViewSubItem[]
                  { new ListViewItem.ListViewSubItem(item, "File"), 
                   new ListViewItem.ListViewSubItem(item, 
file.LastAccessTime.ToShortDateString())};
                string sss = file.Directory + "\\" + file.Name;
                imageList1.Images.Add(Win32API.Shell32.GetFolderIcon(sss, false));
                listView1.View = View.SmallIcon;
                // item.Position+"\\"+item.Name

                // imageList1.Images.Add(Win32API.Shell32.GetFolderIcon(file, false));

                //item.SubItems.AddRange(subItems);
                //listView1.Items.Add(sss, nIndex++);
                listView1.Items.Add(item);
            }

            listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
        }
        void treeView1_NodeMouseClick(string ss) 
        {
/*
            DirectoryInfo nodeDirInfo = (DirectoryInfo)listView1.Tag;
           // newSelected = e.Node;
            listView1.Items.Clear();
          
           // newSelected.Tag += ss;
        
           
            ListViewItem.ListViewSubItem[] subItems;
            ListViewItem item = null;

            foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())
            {
                item = new ListViewItem(dir.Name, 0);
                subItems = new ListViewItem.ListViewSubItem[]
                  {new ListViewItem.ListViewSubItem(item, "Directory"), 
                   new ListViewItem.ListViewSubItem(item, 
dir.LastAccessTime.ToShortDateString())};
                //item.
                item.SubItems.AddRange(subItems);
                listView1.Items.Add(item);
            }
            listView1.SmallImageList = imageList1;
            listView1.LargeImageList = imageList1;
            foreach (FileInfo file in nodeDirInfo.GetFiles())
            {
                item = new ListViewItem(file.Name, 1);
                subItems = new ListViewItem.ListViewSubItem[]
                  { new ListViewItem.ListViewSubItem(item, "File"), 
                   new ListViewItem.ListViewSubItem(item, 
file.LastAccessTime.ToShortDateString())};
                string sss = file.Directory + "\\" + file.Name;
                imageList1.Images.Add(Win32API.Shell32.GetFolderIcon(sss, false));
                listView1.View = View.SmallIcon;
                // item.Position+"\\"+item.Name

                // imageList1.Images.Add(Win32API.Shell32.GetFolderIcon(file, false));

                //item.SubItems.AddRange(subItems);
                //listView1.Items.Add(sss, nIndex++);
                listView1.Items.Add(item);
            }

            listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);*/


        }
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            //openFileDialog1.InitialDirectory = "";
            openFileDialog1.Filter = "All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;

            //   listView1.SmallImageList = imageList1;
            listView1.LargeImageList = imageList1;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string fName = openFileDialog1.FileName;
                imageList1.Images.Add(Win32API.Shell32.GetFolderIcon(fName, false));
                listView1.View = View.LargeIcon;
                //Add file name and icon to listview
                listView1.Items.Add(fName, nIndex++);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int[] _iconIndex = new int[] { 8, 3, 4, 0x22, 15, 0x7e, 0x7f, 0x80, 0x81, 11 };
            for (int i = 0; i < _iconIndex.Length; i++)
            {
                Win32API.Shell32.GetShellIcon(_iconIndex[i], Win32API.Shell32.IconSize.Large).ToBitmap().Save("D:\\ShellIconDemo\\" + _iconIndex[i].ToString() + ".jpg");
            }
        }

        private void listView1_SelectedIndexChanged(object sender,ListViewItemSelectionChangedEventArgs e)
        
        {

            DirectoryInfo nodeDirInfo = (DirectoryInfo)e.Item.Tag; ;
            ListView.SelectedListViewItemCollection selected = listView1.SelectedItems;
            e.Item.Tag = newSelected.Tag + selected[0].SubItems[0].Text+"\\";
//            newSelected = e.Item.Tag;
           // newSelected.FullPath = e.Item.Tag;
            nodeDirInfo = new DirectoryInfo(e.Item.Tag.ToString());

            Console.WriteLine(  selected[0].SubItems[0].Text);
            treeView1_NodeMouseClick(selected[0].SubItems[0].Text);


            //DirectoryInfo nodeDirInfo = (DirectoryInfo)listView1.Tag;
            // newSelected = e.Node;
            listView1.Items.Clear();

            // newSelected.Tag += ss;


            ListViewItem.ListViewSubItem[] subItems;
            ListViewItem item = null;

            foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())
            {
                item = new ListViewItem(dir.Name, 0);
                subItems = new ListViewItem.ListViewSubItem[]
                  {new ListViewItem.ListViewSubItem(item, "Directory"), 
                   new ListViewItem.ListViewSubItem(item, 
dir.LastAccessTime.ToShortDateString())};
                //item.
                item.SubItems.AddRange(subItems);
                listView1.Items.Add(item);
            }
            listView1.SmallImageList = imageList1;
            listView1.LargeImageList = imageList1;
            foreach (FileInfo file in nodeDirInfo.GetFiles())
            {
                item = new ListViewItem(file.Name, 1);
                subItems = new ListViewItem.ListViewSubItem[]
                  { new ListViewItem.ListViewSubItem(item, "File"), 
                   new ListViewItem.ListViewSubItem(item, 
file.LastAccessTime.ToShortDateString())};
                string sss = file.Directory + "\\" + file.Name;
                imageList1.Images.Add(Win32API.Shell32.GetFolderIcon(sss, false));
                listView1.View = View.SmallIcon;
                // item.Position+"\\"+item.Name

                // imageList1.Images.Add(Win32API.Shell32.GetFolderIcon(file, false));

                //item.SubItems.AddRange(subItems);
                listView1.Items.Add(sss, nIndex++);
                listView1.Items.Add(item);
            }

            listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
        }
    }

1 則留言:

  1. hi friend,

    can you send email me for example project file

    回覆刪除