问题1:是这样,我想做一个用户控件,用来选择路径,外观如ComboBox,点击后弹出一个TreeView,它的外观和功能与FolderBrowserDialog里的那个树视图一样,现在其他的已解决,但有一个和图标绘制有关的问题。
我的图标是从文件(文件夹或文件)中提取的,用API函数!在绘制的时候,如果有多个Device,如32X32 16*16等,如何绘制指定尺寸的呢?用Graphics的DrawIcon绘制出来的图标只是将32X32的给缩小了,视觉效果有点差!问题2:怎么样判断回收站内是空还是懑?怎么样像打开回收站一样取得回收站里的文件?请高人指点下,谢谢!

解决方案 »

  1.   

    DrawIconEx[DllImport("shell32.dll")]
    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.   

    1、调用SHGetFileInfo函数,uFlags参数给SHGFI_ICON|SHGFI_LARGEICON取大图标,SHGFI_ICON|SHGFI_SMALLICON取小图标。
    2、可以直接访问回收站文件夹,或者找找看系统有没有提供接口。
      

  3.   

    第一个问题似乎已经有答案第二个问题以前有人问过,现在我找出来帮你转一下吧:作者好像叫:李俊俊正文如下:我们知道视窗系统是把我们将要删除的文件信息都临时保存   
      在"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
      

  4.   

    关于第二个问题,你说访问文件夹,我找到一个SHGetSpecialFolderLocation/Path,好象参数是CSIDL,这里面好像定义的一个关于回收站的常量,这个方法行不行呢,本来前两天我对这个还允满信心,但这两天越看越不满意,一个方面是,我想尽量模仿FolderBrowseDialog的效果,所以桌面,我的文档,网上邻居什么的那些图标都是从Shell32.dll中直接提取的,这样一旦应用了新的桌面主题,我的这个控件中图标不跟着变!我现在通过检查注册表来解决这个问题,有点“笨”!按我想的应当是通过这些SH开头的Shell API应该所有的问题都能搞定
    我还是将问题问的细点吧,比如我的控件中在桌面节点下面,首先是手动添加我的文档,我的电脑,网上邻居回收站什么的,然后再扫一遍“桌面”的物理文件夹,将桌面上的文件夹再添加上,这里涉及一个问题,如果在桌面上有一个快捷方式,还有一个确定它指向的目标是文件还是文件夹的问题,还有我的电脑它不对应物理目录,那怎么添加该计算机上其他用户的“我的文档的”,就是打开桌面我的电脑后在驱动器列表上方都会有“共享文档”,“《用户名》的文档”等等,不知道WinRAR软件的“解压到”对话框是怎么做的,我想即然能做出来,就肯定不会像上面一样去“一个一个找”,是不是涉及Shell扩展编程?问题没完,稍后结贴,楼上几个热心的朋友幸苦了!再接再厉呀,就是给个思路也好呀!
      

  5.   

    如果你是要做一个选择路径的控件,建议你不要显示回收站。
    桌面以及“我的电脑”、“我的文档”等的路径可以用Shell API获取,桌面上的其它文件夹都在桌面路径下。快捷方式可以当作文件来看待。
      

  6.   

    是的,在综合考虑了各方面因素后我把回收站去除了!我的电脑,我的文档和网上邻居是手动添加的,快捷方式的问题也好解决。
    我想再问楼上的:在FolderBrowserDialog中,打开我的电脑节点后是本机的驱动器,下面还有“共享文档”(我知道如何获取这个了)和本机其他用户的文档,名为“[用户名] 的文档”,这个要怎么弄,难首要选找出本机上有多少个用户?第二个问题是最关键的。如何将网上邻居节点弄的跟FolderBrowserDialog一样?就是点开后有三个地球图标,其中一个还有WorkGroup,怎么显示工作组内的其他计算机?就算不能和FolderBrowserDialog完全一样但至少要显示工作组的计算机吧?
    还有一个具体的问题:LoadImage 这个API函数可以从文件中加载图标,但我调用的时候,如果文件是.ico文件,函数调用就能成功,如果是.dll或.exe文件就不行!具体的情况是我想从Shell32.dll中提取指定的图标,就是索引为34的“桌面”,第一个参数hint我是用LoadLibrary取得的,第二个参数它说用MAKEINTSOURCE宏,我看了一下在头文件中的定义,直接将其转换成了字符串!不知道是不是这两个参数有问题?
    以上几个问题如果要用到Shell Api的话具体是哪个函数呢?麻烦楼上的或后来的老师们再给个API函数的原型声明,谢谢,需要说明的是不是我这个人懒,而是这几天我一直尝试Shell API,但里面有几个函数,调用就是不成功,百思而不解,怀疑是不是我的原型声明有问题!
      

  7.   

    1、如果要显示全部用户,可以先获取“用户”路径,再取下面的子目录。我觉得只显示当前用户的文档目录即可,其它用户的文档有可能没有权限访问。
    2、这个不清楚有没有接口可以调用,自己查找太复杂了。
    3、取可执行文件中的图标可以用ExtractIcon。另外提一点,如果你要实现与系统浏览对话框一样的效果,可以尝试直接使用系统的对话框,在回调函数中或者借助定时或Hook,用SetWindowLong给对话框加上WS_CHILD风格,并调整位置和大小,使其嵌到自己的窗口中。
      

  8.   

    终于可以结贴了!!!!不枉我这几天的忙碌,也暂不管可移植性怎么样,最起码效果我觉得还是凑合的。如下两图:
    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里面“整个网络”下还是有东西的,不知道问题在哪?如果有知道的,麻烦分享一下。尽管要结帖了,但我想信总会有无私奉献的人的!