问题1:是这样,我想做一个用户控件,用来选择路径,外观如ComboBox,点击后弹出一个TreeView,它的外观和功能与FolderBrowserDialog里的那个树视图一样,现在其他的已解决,但有一个和图标绘制有关的问题。
我的图标是从文件(文件夹或文件)中提取的,用API函数!在绘制的时候,如果有多个Device,如32X32 16*16等,如何绘制指定尺寸的呢?用Graphics的DrawIcon绘制出来的图标只是将32X32的给缩小了,视觉效果有点差!问题2:怎么样判断回收站内是空还是懑?怎么样像打开回收站一样取得回收站里的文件?请高人指点下,谢谢!
我的图标是从文件(文件夹或文件)中提取的,用API函数!在绘制的时候,如果有多个Device,如32X32 16*16等,如何绘制指定尺寸的呢?用Graphics的DrawIcon绘制出来的图标只是将32X32的给缩小了,视觉效果有点差!问题2:怎么样判断回收站内是空还是懑?怎么样像打开回收站一样取得回收站里的文件?请高人指点下,谢谢!
解决方案 »
- SOCKET问题
- 求一个正则表达式
- NHibernate 设置参数报错 Parameter does not exist as a named parameter i
- C#中如何弹出提示确认信息框?或者说,如何在C#类中接受提示确认信息框的返回值?
- VS 2005中 有没有地方 写开发文档?
- .net remoting中如果使用客户端激活,服务端怎么获取客户端new出来的远程组件啊?
- 这个Web Service客户端的Polling或者Callback如何写?高分求助,问题解决,立马送分!!
- 大家帮我看看
- 请问WinFrom中的怎么得到Combobox控件中某一项的text和value值
- GDI+问题:请问绘制ToolBar里的ComboBox的列表框?
- 利用委托实现windowfrom中两个窗体的值实时相等。
- c#中的Ilist的传递过程中的值被改变的问题?
private static extern int SHFileOperation([In, Out] _SHFILEOPSTRUCT str);[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class _SHFILEOPSTRUCT
{
public IntPtr hwnd;
public UInt32 wFunc;
public string pFrom;
public string pTo;
public UInt16 fFlags;
public Int32 fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}
2、可以直接访问回收站文件夹,或者找找看系统有没有提供接口。
在"C:\Recycled"目录下面。在通过"清空回收站"按钮来彻底此目录下
的要删除的文件的。本程序的主要思路就是根据以上知识得来的。具体说
明如下:
(1).首先判断C盘根目录下面的"Recycled"目录是否为空。
(2).如果不为空的话,就遍历所有文件信息,并删除文件。
二.程序设计和运行环境
(1).视窗系统2000专业版本
(2)..Net FrameWork SDK Beta 2
& #160;三.程序设计的主要步骤和具体解释
(1).如何判断C盘根目录下面的"Recycled"目录是否为空。
要判断"C:\Recycled"目录中是否有文件信息,要经过二个步
骤,首先要确定找到此目录。其次才能够判断此目录是否为空。下面就按
照这二个步骤来分别做具体介绍:
i>.如何在程序中找到"C:\Recycled"目录。
在.Net FrameWork SDK中封装了一个名称空间--System.IO。
此名称空间中定义了许多与文件和目录处理相关的类、对象、属性和方
法。Visual C#就是通过灵活调用这些资源来实现对文件和目录的具体
操作的。本文中主要用到此名称空间中的二个类:Directory类和File
类。前者在程序中主要用来处理和目录相关的操作的,如确定目录和获得
目录中的文件信息。后者在程序中主要用来处理和文件相关的操作的,如
删除文件。在程序中用到Directory类中的GetFiles ( "目录名称")
方法,此方法的返回的是一个枚举型,此枚举型是由一组字符串组成。
GetFiles()方法是把在目录中的每个文件名称都形成一个字符串,然
后由这些字符串组成形成一个枚举类型。
ii>.判断此目录是否为空。
在此要介绍一下foreach语句,Visual C#是通过此语句来收集
枚举的。在本文中是通过他来列举出在"C:\Recycled"存在的所有被删
除的文件信息的。
int c = 0 ; // 定义此变量主要是来判断目录中是否有文件
foreach ( string s1 in Directory.G etFiles
( "c:\\recycled" ) ) // 返回文件名称字符串行时的枚举类型
{
++c ;
}
if ( c > 0 ) //判断是否存在文件如果 c > 0则回收站有文件,
反之则没有
{
…..
}
(2).如果"C:\Recycled"目录中不为空的话,就遍历目录中的
所有文件信息,并删除文件。
在本段落里面要介绍一下MessageBox类的用法。用过VB和
Delphi的人一定知道在此类程序设计语言中,显示提示信息是一件多么
容易的事情。但在Visual C#中,这类操作显然相对繁琐些,但在灵活
程度有了一定的提高。在Visual C#中,System.Windows.Forms名称
空间中封装了一个MessageBox的类,在此类中又定义了与显示提示信息
相关的一些方法(Show方法)、对象和属性。在本程序中就有关于
MessageBox类的具体介绍。
要删除磁盘上的文件就要使用到名称空间System.IO中File类的
Delete ( )方法。Delete ( )方法后面跟的参数是文件所在磁盘的全
路径名称。要获得文件的全路径名称,就还要使用到foreach语句,程序
中就是foreach语句来从一个包含所有文件全路径名称的枚举类型中获得
文件的全路径名称的。具体实现语句如下:
if ( c > 0 ) // 判断"C:\Recycled"目录中是否存在文件信息
{
DialogResult r = MessageBox.Show ( "是否确定?" , "垃 圾处理!" ,
MessageBoxButtons.YesNo ,
MessageBoxIcon.Question ) ;
// 显示"确定"和"取消"二个按钮,图标显示是一个问号。
int ss=(int)r ;
if ( ss==6 ) // 按动确定按钮
{ foreach ( string s in Directory.GetFiles
( "c:\\recycled" ) )
// 把全路径名称房子 s中
{
File.Delete ( s ) ; //删除此文件
}
}
}
四.程序的源代码(recycled.cs)、编译方法及运行后的界面:
(1).程序的源代码:recycled.cs:
using System.IO ;
using System.Windows.Forms ; //导入程序中用到的名称空间
class Recycle
{
public static void Main ( )
{
int c = 0 ; // 定义此变量主要是来判断目录中是否有文件
foreach ( string s1 in Directory.GetFiles
( "c:\\recycled" ) ) // 返回文件名称字符串行时的枚举类型
{
++c ;
}
if ( c > 0 ) //判断是否存在文件如果 c > 0则回收站有文件,
反之则没有
{
DialogResult r = MessageBox.Show ( "是否确定?" , "垃
圾处理!" ,
MessageBoxButtons.YesNo ,
MessageBoxIcon.Question ) ;
// 显示"确定"和"取消"二个按钮,图标显示是一个问号。
int ss=(int)r ;
if ( ss==6 ) // 按动确定按钮
{ foreach ( string s in Directory.GetFiles
( "c:\\recycled" ) )
// 把全路径名称房子 s中
{
File.Delete ( s ) ; //删除此文件
}
}
}
}
}
(2).编译方法:
在经过如下命令行进行编译后,就形成了一个Windows 的执行文
件--recycled.exe。
csc /t:winexe /r:system.dll /r:system.windows.forms.dll
recycled.cs
我还是将问题问的细点吧,比如我的控件中在桌面节点下面,首先是手动添加我的文档,我的电脑,网上邻居回收站什么的,然后再扫一遍“桌面”的物理文件夹,将桌面上的文件夹再添加上,这里涉及一个问题,如果在桌面上有一个快捷方式,还有一个确定它指向的目标是文件还是文件夹的问题,还有我的电脑它不对应物理目录,那怎么添加该计算机上其他用户的“我的文档的”,就是打开桌面我的电脑后在驱动器列表上方都会有“共享文档”,“《用户名》的文档”等等,不知道WinRAR软件的“解压到”对话框是怎么做的,我想即然能做出来,就肯定不会像上面一样去“一个一个找”,是不是涉及Shell扩展编程?问题没完,稍后结贴,楼上几个热心的朋友幸苦了!再接再厉呀,就是给个思路也好呀!
桌面以及“我的电脑”、“我的文档”等的路径可以用Shell API获取,桌面上的其它文件夹都在桌面路径下。快捷方式可以当作文件来看待。
我想再问楼上的:在FolderBrowserDialog中,打开我的电脑节点后是本机的驱动器,下面还有“共享文档”(我知道如何获取这个了)和本机其他用户的文档,名为“[用户名] 的文档”,这个要怎么弄,难首要选找出本机上有多少个用户?第二个问题是最关键的。如何将网上邻居节点弄的跟FolderBrowserDialog一样?就是点开后有三个地球图标,其中一个还有WorkGroup,怎么显示工作组内的其他计算机?就算不能和FolderBrowserDialog完全一样但至少要显示工作组的计算机吧?
还有一个具体的问题:LoadImage 这个API函数可以从文件中加载图标,但我调用的时候,如果文件是.ico文件,函数调用就能成功,如果是.dll或.exe文件就不行!具体的情况是我想从Shell32.dll中提取指定的图标,就是索引为34的“桌面”,第一个参数hint我是用LoadLibrary取得的,第二个参数它说用MAKEINTSOURCE宏,我看了一下在头文件中的定义,直接将其转换成了字符串!不知道是不是这两个参数有问题?
以上几个问题如果要用到Shell Api的话具体是哪个函数呢?麻烦楼上的或后来的老师们再给个API函数的原型声明,谢谢,需要说明的是不是我这个人懒,而是这几天我一直尝试Shell API,但里面有几个函数,调用就是不成功,百思而不解,怀疑是不是我的原型声明有问题!
2、这个不清楚有没有接口可以调用,自己查找太复杂了。
3、取可执行文件中的图标可以用ExtractIcon。另外提一点,如果你要实现与系统浏览对话框一样的效果,可以尝试直接使用系统的对话框,在回调函数中或者借助定时或Hook,用SetWindowLong给对话框加上WS_CHILD风格,并调整位置和大小,使其嵌到自己的窗口中。
http://hi.csdn.net/attachment/201004/17/2430265_1271511585INQQ.jpg
针对以上提过的问题可以总结一下:
最重要的是这个自定义的控件用的是COM 不是API,我找了个Shell23.dll,用到的对象是ShellClass,IShellFolder和ShellFolderItem。
1。针对桌面上的任何对象,可以用ShellClass的namespace(object vDir)方法获得桌面项,注意这个与检索DeskTop的特殊目录不同,它可以得到我的电脑,我的文档,回收站,网上邻居甚至是IE,一句话,只要你在桌面上看到的,都有!因此之前手动添加这些东西的步骤就不用了!
2关于本机上所有用户的“《用户名》的文档”的问题,
1》找到“我的电脑”的路径(其实这个是虚目录,我不知道这样称乎对不对,因为文件系统不存在该目录),这个可通过shellclass的namespace(0)得到的项(FolderItem类型)的Path属性得到。
2》上面得到的“我的电脑”的路径再传给namespace方法,这一步后你会发现它不仅列出了本机的所有用户的“文档”,同时出来的还有“共享文档”,控制面板,和本机的驱动器列表。不失一般性,你可以用该方法按目录树的结构递归调用指目录下面的子项即可,需要特殊处理的只是筛选符合你条件的项,及图标的即时获取。
3关于图标的绘制:其实采用以上方法其本上不再需要特殊的处理了,因为凡是桌面上“我的电脑”、回收站什么的,检查其FolderItem.Path项会发现其值为“::”加一个CLRID,使用它们作为参数传递给SHGetFileInfo的话直接就可以得到需要的图标,更重要的是它是与你当前的桌面主题同步的,效果见上图!最后一点是不足,我这个控件现在对于网上邻居只能处理到下一组,就是网上邻居下可以显示出现在里面的“邻居”和“整个网络”但无法处理无法处理“整个网络”下面的节点,因为我见FolderBrowserDialog里面“整个网络”下还是有东西的,不知道问题在哪?如果有知道的,麻烦分享一下。尽管要结帖了,但我想信总会有无私奉献的人的!