c#用Treeview实现FolderBrowerDialog 和动态获取系统图标(运用了Win32 dll类库)
程序员文章站
2023-12-14 08:44:28
事情是这样子的。我需要做一个下面的东东:
这个不难啊,然后就用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啦。
作者:lanny☆兰东才
出处:http://www.cnblogs.com/damonlan
q q:*********
e_mail:damon_lan@163.com or dongcai.lan@hp.com
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。