c#用Treeview實(shí)現(xiàn)FolderBrowerDialog 和動(dòng)態(tài)獲取系統(tǒng)圖標(biāo)(運(yùn)用了Win32 dll類庫(kù))
事情是這樣子的。我需要做一個(gè)下面的東東:
這個(gè)不難啊,然后就用FolderBrowerDialog這個(gè)神器,嗯 還不錯(cuò),剛開始客戶用了也很喜歡。
可是過(guò)了一段時(shí)間之后,客戶說(shuō) 要屏蔽右鍵功能,他不想讓其他通過(guò)右鍵能打開或?yàn)g覽文件夾,如下面 紅色要給屏蔽。
我一開始以為只是一個(gè)參數(shù)問題,就爽快的答應(yīng)了客戶咯??墒前『髞?lái)找啊找 找到天荒地老也木有找到。。。放棄了,然后改用了TreeView。。結(jié)果,版本出來(lái)了,先截圖:
好吧,確實(shí)很丑哦。。
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;
}
}
}
雖然 這個(gè)時(shí)候,把右鍵點(diǎn)擊功能給取消啦,但是接著用戶提了三個(gè)要求:
1.需要系統(tǒng)自動(dòng)匹配它的圖標(biāo)
2.要有磁盤容量的大小。。
好吧,然后最后修改一下。這里面用到了 Win32 dll的幾個(gè)函數(shù),確實(shí)很好用呢。。贊一個(gè)。。
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;
}
}
}
結(jié)果如下:
核心代碼是:
[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;
}
很好懂呢,只需要在程序中調(diào)用一下就ok啦。
作者:Lanny☆蘭東才
出處:http://www.cnblogs.com/damonlan
Q Q:*********
E_mail:Damon_lan@163.com or Dongcai.lan@hp.com
本博文歡迎大家瀏覽和轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,在『參考』的文章中,我會(huì)表明參考的文章來(lái)源,尊重他人版權(quán)。若您發(fā)現(xiàn)我侵犯了您的版權(quán),請(qǐng)及時(shí)與我聯(lián)系。
相關(guān)文章
C#實(shí)現(xiàn)兩個(gè)時(shí)間相減的方法
這篇文章主要介紹了C#實(shí)現(xiàn)兩個(gè)時(shí)間相減的方法,實(shí)例分析了C#針對(duì)時(shí)間操作的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01C#版的 Escape() 和 Unescape() 函數(shù)分享
從網(wǎng)上看到兩個(gè)方法, C# 版的 Escape() 和 Unescape(),收藏下。2011-05-05.net4.5使用async和await異步編程實(shí)例
.net4.5使用async和await異步編程實(shí)例,大家參考使用吧2013-12-12c# socket心跳超時(shí)檢測(cè)的思路(適用于超大量TCP連接情況下)
這篇文章主要介紹了c# socket心跳超時(shí)檢測(cè)的思路(適用于超大量TCP連接情況下),幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-03-03