用Treeview实现FolderBrowerDialog 和动态获取系统图标(运用了Win32 dll类库)
2013-03-02 20:10 随风浪迹天涯 阅读(1328) 评论(4) 编辑 收藏 举报其实,FolderBrowerDialog 很好用呢,有木有啊亲。反正我特别的喜欢,微软大哥把这个浏览文件夹的东东封装的多好呀,可是遇到一个变态的客户就不好玩了。
事情是这样子的。我需要做一个下面的东东:
这个不难啊,然后就用FolderBrowerDialog这个神器,嗯 还不错,刚开始客户用了也很喜欢。
可是过了一段时间之后,客户说 要屏蔽右键功能,他不想让其他通过右键能打开或浏览文件夹,如下面 红色要给屏蔽。
我一开始以为只是一个参数问题,就爽快的答应了客户咯。可是啊后来找啊找 找到天荒地老也木有找到。。。放弃了,然后改用了TreeView。。结果,版本出来了,先截图:
好吧,确实很丑哦。。
public MyDirectory() { InitializeComponent(); treeViewDirectory.BeginUpdate(); label1.Text = folderTitle; treeViewDirectory.ImageList = imageList1; treeViewDirectory.SelectedImageIndex = 3; EnumDrivers(); treeViewDirectory.EndUpdate(); this.SetBounds((Screen.GetBounds(this).Width / 2) - (this.Width / 2), (Screen.GetBounds(this).Height / 2) - (this.Height / 2), this.Width, this.Height, BoundsSpecified.Location); } public static string folderTitle = ""; private void EnumDrivers() { //treeViewDirectory.ImageIndex = 1; string[] allDriveNames = Directory.GetLogicalDrives(); TreeNode rootNode = new TreeNode(); rootNode.Text = "My Computer"; rootNode.ImageIndex = 1; rootNode.Expand(); treeViewDirectory.Nodes.Add(rootNode); treeViewDirectory.SelectedNode = rootNode.FirstNode; DriveInfo[] allDrives = DriveInfo.GetDrives(); int j = 0; try { int i = 0; foreach (DriveInfo d in allDrives) { TreeNode tn = new TreeNode(d.Name); // GetIcon(d.Name, false) this.imageList1.Images.Add(GetIcon(d.Name, false)); tn.ImageIndex = 2; tn.Tag = d.RootDirectory.FullName; treeViewDirectory.Nodes[0].Nodes.Add(tn); treeViewDirectory.Nodes[0].Nodes[j].Text = d.Name ; ShowDirs(tn); j++; } } catch (System.Exception) { } } private void ShowDirs(TreeNode tn) { tn.Nodes.Clear(); try { DirectoryInfo DirInfo = new DirectoryInfo(tn.Tag.ToString()); if (!DirInfo.Exists) { return; } else { DirectoryInfo[] Dirs; try { Dirs = DirInfo.GetDirectories(); } catch (Exception e) { return; } foreach (DirectoryInfo Dir in Dirs) { TreeNode dir = new TreeNode(Dir.Name); dir.ImageIndex = 0; dir.Tag = Dir.FullName; tn.Nodes.Add(dir); } } } catch (System.Exception) { } } private void treeViewDirectory_BeforeExpand(object sender, TreeViewCancelEventArgs e) { treeViewDirectory.BeginUpdate(); foreach (TreeNode tn in e.Node.Nodes) { ShowDirs(tn); } treeViewDirectory.EndUpdate(); } public static string myValue { set; get; } private void btnOK_Click(object sender, EventArgs e) { MyDirectory.myValue = lastResult; this.Close(); } private void btnCancel_Click(object sender, EventArgs e) { MyDirectory.myValue = null; this.Close(); } private static string lastResult = null; private void treeViewDirectory_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { lastResult = null; string result = e.Node.FullPath; if (result != "My Computer") { if (result.Contains(@"My Computer\") || result.Contains("My Computer")) { int len = 0; if (result.Contains(@"My Computer\")) { len = @"My Computer\".Length; } else { len = "My Computer".Length; } result = result.Substring(len); return result; } } }
虽然 这个时候,把右键点击功能给取消啦,但是接着用户提了三个要求:
1.需要系统自动匹配它的图标
2.要有磁盘容量的大小。。
好吧,然后最后修改一下。这里面用到了 Win32 dll的几个函数,确实很好用呢。。赞一个。。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System.Runtime.InteropServices; namespace HP.DMT.UI { public partial class MyDirectory : Form { public MyDirectory() { InitializeComponent(); treeViewDirectory.BeginUpdate(); label1.Text = folderTitle; treeViewDirectory.ImageList = imageList1; treeViewDirectory.SelectedImageIndex = 3; EnumDrivers(); treeViewDirectory.EndUpdate(); this.SetBounds((Screen.GetBounds(this).Width / 2) - (this.Width / 2), (Screen.GetBounds(this).Height / 2) - (this.Height / 2), this.Width, this.Height, BoundsSpecified.Location); } public static string folderTitle = ""; private void EnumDrivers() { //treeViewDirectory.ImageIndex = 1; string[] allDriveNames = Directory.GetLogicalDrives(); TreeNode rootNode = new TreeNode(); rootNode.Text = "My Computer"; rootNode.ImageIndex = 1; rootNode.Expand(); treeViewDirectory.Nodes.Add(rootNode); treeViewDirectory.SelectedNode = rootNode.FirstNode; DriveInfo[] allDrives = DriveInfo.GetDrives(); int j = 0; try { int i = 0; foreach (DriveInfo d in allDrives) { TreeNode tn = new TreeNode(d.Name); // GetIcon(d.Name, false) this.imageList1.Images.Add(GetIcon(d.Name, false)); tn.ImageIndex = 4 + i; i++; tn.Tag = d.RootDirectory.FullName; treeViewDirectory.Nodes[0].Nodes.Add(tn); if (d.DriveType.ToString() == "Fixed") { treeViewDirectory.Nodes[0].Nodes[j].Text = d.Name + "(" + d.DriveType.ToString() + "," + d.TotalFreeSpace / 1024 / 1024 / 1024 + "G/" + d.TotalSize / 1024 / 1024 / 1024 + "G)"; } else { treeViewDirectory.Nodes[0].Nodes[j].Text = d.Name + "(" + d.DriveType.ToString() + ")"; } ShowDirs(tn); j++; } } catch (System.Exception) { } } private void ShowDirs(TreeNode tn) { tn.Nodes.Clear(); try { DirectoryInfo DirInfo = new DirectoryInfo(tn.Tag.ToString()); if (!DirInfo.Exists) { return; } else { DirectoryInfo[] Dirs; try { Dirs = DirInfo.GetDirectories(); } catch (Exception e) { return; } foreach (DirectoryInfo Dir in Dirs) { TreeNode dir = new TreeNode(Dir.Name); dir.ImageIndex = 0; dir.Tag = Dir.FullName; tn.Nodes.Add(dir); } } } catch (System.Exception) { } } private void treeViewDirectory_BeforeExpand(object sender, TreeViewCancelEventArgs e) { treeViewDirectory.BeginUpdate(); foreach (TreeNode tn in e.Node.Nodes) { ShowDirs(tn); } treeViewDirectory.EndUpdate(); } public static string myValue { set; get; } private void btnOK_Click(object sender, EventArgs e) { MyDirectory.myValue = lastResult; this.Close(); } private void btnCancel_Click(object sender, EventArgs e) { MyDirectory.myValue = null; this.Close(); } private static string lastResult = null; private void treeViewDirectory_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { lastResult = null; string result = e.Node.FullPath; if (result != "My Computer") { if (result.Contains(@"My Computer\") || result.Contains("My Computer")) { int len = 0; if (result.Contains(@"My Computer\")) { len = @"My Computer\".Length; } else { len = "My Computer".Length; } result = result.Substring(len); char[] arrs = result.ToCharArray(); int beforLenth = result.Remove(result.IndexOf('/') + 1).Length; int afterLenth = result.Substring(result.IndexOf('/') + 1).Remove(result.Substring(result.IndexOf('/') + 1).IndexOf(')')).Length; char[] c = { ')' }; string str1 = result.Substring(0, 3); string str2 = result.Substring(result.IndexOfAny(c, beforLenth + afterLenth, 1) + 1); lastResult = str1 + str2; } } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; } [DllImport("Shell32.dll", EntryPoint = "SHGetFileInfo", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags); [DllImport("User32.dll", EntryPoint = "DestroyIcon")] public static extern int DestroyIcon(IntPtr hIcon); public const uint SHGFI_ICON = 0x100; public const uint SHGFI_LARGEICON = 0x0; public const uint SHGFI_SMALLICON = 0x1; public const uint SHGFI_USEFILEATTRIBUTES = 0x10; static Icon GetIcon(string fileName, bool isLargeIcon) { SHFILEINFO shfi = new SHFILEINFO(); IntPtr hI; if (isLargeIcon) hI = MyDirectory.SHGetFileInfo(fileName, 0, ref shfi, (uint)Marshal.SizeOf(shfi), MyDirectory.SHGFI_ICON | MyDirectory.SHGFI_USEFILEATTRIBUTES | MyDirectory.SHGFI_LARGEICON); else hI = MyDirectory.SHGetFileInfo(fileName, 0, ref shfi, (uint)Marshal.SizeOf(shfi), MyDirectory.SHGFI_ICON | MyDirectory.SHGFI_USEFILEATTRIBUTES | MyDirectory.SHGFI_SMALLICON); Icon icon = Icon.FromHandle(shfi.hIcon).Clone() as Icon; MyDirectory.DestroyIcon(shfi.hIcon); return icon; } } }
结果如下:
核心代码是:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; } [DllImport("Shell32.dll", EntryPoint = "SHGetFileInfo", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags); [DllImport("User32.dll", EntryPoint = "DestroyIcon")] public static extern int DestroyIcon(IntPtr hIcon); public const uint SHGFI_ICON = 0x100; public const uint SHGFI_LARGEICON = 0x0; public const uint SHGFI_SMALLICON = 0x1; public const uint SHGFI_USEFILEATTRIBUTES = 0x10; static Icon GetIcon(string fileName, bool isLargeIcon) { SHFILEINFO shfi = new SHFILEINFO(); IntPtr hI; if (isLargeIcon) hI = MyDirectory.SHGetFileInfo(fileName, 0, ref shfi, (uint)Marshal.SizeOf(shfi), MyDirectory.SHGFI_ICON | MyDirectory.SHGFI_USEFILEATTRIBUTES | MyDirectory.SHGFI_LARGEICON); else hI = MyDirectory.SHGetFileInfo(fileName, 0, ref shfi, (uint)Marshal.SizeOf(shfi), MyDirectory.SHGFI_ICON | MyDirectory.SHGFI_USEFILEATTRIBUTES | MyDirectory.SHGFI_SMALLICON); Icon icon = Icon.FromHandle(shfi.hIcon).Clone() as Icon; MyDirectory.DestroyIcon(shfi.hIcon); return icon; }
很好懂呢,只需要在程序中调用一下就ok啦。
--------------------2013.8.6 modify--------------------
//Get Stroage Path private void btnOpenFolder_Click(object sender, EventArgs e) { string storagePath = WinFileManage.OpenFolderAndGetPath(this); if (storagePath != "") tbStoragePath.Text = storagePath; }
然后新建一个WinFileManger
class WinFileManage { //If needed, we can add more parameters for this function public static string OpenFolderAndGetPath(IWin32Window owner) { FolderBrowserDialogEx fbde = new FolderBrowserDialogEx(); fbde.Title = "Please select the folder"; fbde.RootFolder = Environment.SpecialFolder.MyComputer; fbde.SelectedPath = ""; //fbde.StartPosition = FormStartPosition.CenterScreen; DialogResult dr = fbde.ShowDialog(owner); if (dr == DialogResult.OK) return fbde.SelectedPath; else return ""; } }
这里需要用到FolderBrowserDialogEx 这个WIN API 函数。
作者:Lanny☆兰东才
出处:http://www.cnblogs.com/damonlan
Q Q:*********
E_mail:Damon_lan@163.com or Dongcai.lan@hp.com
出处:http://www.cnblogs.com/damonlan
Q Q:*********
E_mail:Damon_lan@163.com or Dongcai.lan@hp.com
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。