磁盘分区列表和文件夹列表(treeview应用) 类似资源管理器

  此主题相关图片如下:
按此在新窗口浏览图片


VFP中制作磁盘分区列表和文件夹列表

红飞狐

作为一名程序员,经常要在程序中对磁盘和文件夹进行操作,VB、DELPHI中都有相应的可视控件,但VFP中没有这类控件, 我们通常用Getdir()或将List控件数据源设置为“7-文件”来实现对文件夹的操作, 但界面实在不敢恭维,操作上也不很方便。事实上利用Windows的公用控件结合Windows API函数, 我们也可以制作出类似的VFP可视类(效果见下图)。


                 

例图是我在VFP6.0中制作并放入表单的两个可视类。左边是利用ImageComboBox和ImageList制作的磁盘列表, 右边是利用TreeView和ImageList制作的文件夹列表。好,下面让我们开始吧。
一、制作磁盘列表。
1、选定使用控件。 ImageComboBox、TerrView、ImageList三个控件都包含在MSComctl.ocx中,是随VFP一起安装的。 我这里选用版本的是6.0。使用时最好将他们加入表单控件工具栏,便于选定。 方法是VFP主菜单-〉工具—〉选项,点击控件页面,将此三项选定,然后点击“设置为默认值”。

2、创建新类。 VFP主菜单-〉文件-〉新建-〉新建文件。类命名为DirCom,派生于Control(容器),存储于c:/myvcx/DirCom.Vcx。确定

3、添加控件。点击表单工具栏查看类,选中ActiveX控件,将一个ImageComboBox和ImageList控件放入容器。为使用方便,将Name分别改为Ole1和Ole2。

4、新建属性。VFP主菜单-〉类-〉新建属性。名称定为SelDrv,说明为:“选定驱动器”,并将其值由“.F.”改为空(显示为“(无)”)。

5、设置属性。

  DirCom:

Backstyle=0-透明;

BorderWidth=0     (这样在使用时不带边框)

6、添加图标。点中ImageList,即Ole2,按鼠标右键,选择最后一行“ImageLi…”,进入属性设置。首先一定选中16 x 16,将下面的UseMaskColor选中(这样图标就没有讨厌的背景),然后进入Images页,按“Insert Picture”,加入图标,我这里放入7张图标,依次代表软盘、软盘、硬盘、网络驱动器、光盘、Rom盘、我的电脑。然后点击应用,确定

7、添加代码。

在ImageComboBox,即Ole1的init event中加入以下代码:

*/将列表设置为与容器相适应的宽度

This.width=This.Parent.Width

If This.Width>2

   This.Width=This.Width-2

Endif    

*/调用Windows Api函数获取本机驱动器的符号和类型

Declare Integer GetLogicalDriveStrings In Win32Api Long, string @Alldrv

Declare integer GetDriveType In "kernel32" String

*/用GetLogicalDriveStrings获取所有驱动器,存入Alldrv,其形势为”A:/C:/D:/….”,最后为*/一空字符,应除去

Alldrv=Spac(120)

=GetLogicalDriveStrings(120,@Alldrv)

nQdqs=(len(allt(Alldrv))-1)/4   &&计算驱动器数量

cDqqdq=SyS(5)+"/"           &&获取当前驱动器符号

nDqqdq=1

*/定义三维数组,存放驱动器信息

*/aDrive(n,1)存放驱动器符号

*/aDrive(n,2)存放驱动器类型的汉字名称和符号

*/aDrive(n,3)存放驱动器类型

Dime aDrive(nQdqs,3)

For i=1 To nQdqs

   aDrive(i,1)=Upper(Subs(Alldrv,1,3))    &&依次取出驱动器符号

   If Alltrim(cDqqdq)==aDrive(i,1)

      nDqqdq=I                      &&当前驱动器值

   Endif    

   */调用GetDriveType 函数确定驱动器类型

   nLx=GetDriveType(aDrive(i,1))

   Do Case

      Case nLx=2

           aDrive(i,2)='软盘'

           aDrive(i,3)=2

      Case nLx=3

           aDrive(i,2)='硬盘'

           aDrive(i,3)=3

      Case nLx=4

           aDrive(i,2)='网络驱动器'

           aDrive(i,3)=4

      Case nLx=5

           aDrive(i,2)='光盘'

           aDrive(i,3)=5

      Case nLx=6

           aDrive(i,2)='RAM盘'

           aDrive(i,3)=6

   Endcase

   cDrvName=aDrive(i,1)

   aDrive(i,1)=aDrive(i,2)-Space(2)+Left(aDrive(i,1),Len(cDrvName)-1)

   Alldrv=Subs(Alldrv,5)

Endf

*/下拉列表第一项紧靠左边

This.indentation = 0

*/设置下拉列表关联的ImageList

This.imageList = This.Parent.ole2

This.Comboitems.Add(1,"我的电脑","我的电脑")    &&添加列表第一项

This.Comboitems("我的电脑").image = 7          &&设置第一项图标

*/从第二项起较第一项右缩进2个单位

This.indentation = 2

*/添加本机驱动器符号,名称和图标

For i=2 To nQdqs+1

   This.Comboitems.Add(i,"驱动器"+Alltrim(str(i-1)),aDrive(i-1,1))

   This.Comboitems("驱动器"+Alltrim(str(i-1))).image = aDrive(i-1,3)

Endfor

*/将当前驱动器设置为初始显示值

This.Selecteditem=This.Comboitems("驱动器"+Alltrim(str(nDqqdq)))

 

在Ole1的LostFocus中加入代码:

*/将使用者选定的驱动器存入SelDrv,供使用者调用

If This.Text<>"我的电脑"

     This.Parent.SelDrv=Right(This.Text,2)+"/"

  Else      

     This.Parent.SelDrv=""

Endif

好,你可以保存类,并将其加入表单看看效果。

 

二、制作文件夹列表

这里与制作磁盘列表步骤基本相同,只是将类名改为DirTree,第4步添加三个新属性:

cWjjsx  存放文件夹属性,供程序运行时调用;

Wjjsx   存放使用者要求列出的文件夹属性,即ADIR()函数的5个属性AHRSD的任意组合,最好在说明中加以注明;

Seleml  使用者选定的文件夹。

以上三个属性的初值均必须设为字符型,否则出错。

第6步的图标依次改为软盘、硬盘、网络驱动器、光盘、我的电脑、打开的文件夹、关闭的文件夹、回收站。

将Ole1(即Treeview)属性设置为:

Indentation=5;

LabelEdit=1-Manual;

Linestyle=1-RootLines

添加代码:

在Ole1的Init Event中加入:

*/设置使用者要求显示的文件夹的属性,即ADIR()的文件属性

This.Parent.cWjjsx="D"      &&必须含有”D”,否则ADIR()不会找到文件夹

If "A"$Upper(This.Parent.wjjsx)

   This.Parent.cWjjsx=This.Parent.cWjjsx+"A"   &&普通

Endif

If "H"$Upper(This.Parent.wjjsx)

   This.Parent.cWjjsx=This.Parent.cWjjsx+"H"   &&隐藏

Endif

If "R"$Upper(This.Parent.wjjsx)

   This.Parent.cWjjsx=This.Parent.cWjjsx+"R"   &&只读

Endif

If "S"$Upper(This.Parent.wjjsx)

   This.Parent.cWjjsx=This.Parent.cWjjsx+"S"   &&系统

Endif

*/将Ole1的大小设置为与容器适应

*/以下与ImageComboBox相同部分不再做注释

This.Top=0

This.Left=0

This.Width=This.Parent.Width-1

This.Height=This.Parent.Height-1

Declare Integer GetLogicalDriveStrings In Win32Api Long, string @Alldrv

Declare integer GetDriveType In "kernel32" String

Alldrv=Spac(120)

=GetLogicalDriveStrings(120,@Alldrv)

nQdqs=(len(allt(Alldrv))-1)/4

cDqqdq=SyS(5)+"/"

nDqqdq=1

Dime aDrive(nQdqs,4)    &&这里设为4维数组,多出的用来存放最后不含”/”的文件夹名

For i=1 To nQdqs

   aDrive(i,1)=Upper(Subs(Alldrv,1,3))

   If Alltrim(cDqqdq)==aDrive(i,1)

      nDqqdq=i

   Endif    

   nLx=GetDriveType(aDrive(i,1))

   Do Case

      Case nLx=2

           aDrive(i,2)='软盘'

           aDrive(i,3)=1

      Case nLx=3

           aDrive(i,2)='硬盘'

           aDrive(i,3)=2

      Case nLx=4

           aDrive(i,2)='网络驱动器'

           aDrive(i,3)=3

      Case nLx=5

           aDrive(i,2)='光盘'

           aDrive(i,3)=4

      Case nLx=6

           aDrive(i,2)='RAM盘'

           aDrive(i,3)=2

   Endcase

   cDrvName=aDrive(i,1)

   aDrive(i,4)=aDrive(i,2)-Space(2)+Left(aDrive(i,1),Len(cDrvName)-1)

   Alldrv=Subs(Alldrv,5)

Endf

This.imageList = This.parent.ole2

*/添加根节点:“我的电脑”

=This.Nodes.Add(, , "我的电脑", "我的电脑",5))

*/将本机驱动器作为根节点的子节点加入

For i=1 to nQdqs

   =This.Nodes.Add("我的电脑",4,adrive(i,1) ,aDrive(i,4),adrive(i,3))

Endfor    

*/判断某一驱动器是否有子文件夹,如有,将第一个加入成为其子节点,否则不会显示”+”。

*/这里为了减少加入列表的时间,只加入一个子节点,可以取得同样的效果

For i=1 To nQdqs

   nMls=Adir(aWj,aDrive(i,1)+"*.*",This.Parent.cWjjsx)

   For j=1 To nMls

       If "D"$aWj(j,5)

          =This.Nodes.Add(aDrive(i,1),4,aDrive(i,1)+aWj(j,1),aWj(j,1),7)

          Exit

       Endif

   Endfor

Endfor

*/将当前驱动器设置为选定,这样可以将在开始就将根节点展开,并选中当前驱动器

This.selecteditem=This.Nodes(cDqqdq)

在Ole1的Expand event(展开某一节点)中加入代码:

*/以下两句为系统自动生成

*** ActiveX 控件事件 ***

LPARAMETERS node

*/如果展开根节点,不做处理

If node.Key="我的电脑"

  Retu 0

Endif

*/判断此节点是否曾经展开,如已经展开,不做处理

If Empty(node.tag)

    node.tag="打开"

  Else

    Retu 0

Endif

*/判断展开的节点是否驱动器,如不是将展开图标设置为“打开文件夹”

If Len(node.Key)<>3

  node.Expandedimage=6

Endif  

*/删除第一个子节点,因为为减少展开时间,没有展开过的文件夹只有一个子节点,必须*/删除重新添加所有下级节点

This.nodes.remove(node.child.key)

*/将展开节点的Key(此值唯一)给变量cDqml(当前目录)

cDqml=node.key

cDqsywj=Alltrim(cDqml)+"*.*"

*/利用DIR()将展开的文件夹下的所有文件和文件夹存入aWj_father数组

nWjs_Father=Adir(aWj_father,cDqsywj,This.Parent.cWjjsx)

Dime cNodeKey(nWjs_father,2)

For i=1 To nWjs_father

   */判断文件夹名第一个字符是否“.”或“..”,必须将这两个特殊的文件夹除去

   If left(aWj_father(i,1),1)="."

      cNodeKey(i,2)=.f.

      Loop

   Endif    

   If "D"$aWj_father(i,5)

         cNodeKey(i,1)=cDqml+aWj_father(i,1)+"/"

         cNodeKey(i,2)=.t.

         */判断文件夹是否为回收站,此处我的处理不全面,希望得到指正

         */如为回收站将其图标设为回收站,否则设为“关闭的文件夹”

         If Upper(aWj_father(i,1))<>Upper("Recycled")

              This.Nodes.Add(node,4,cNodeKey(i,1),aWj_father(i,1),7)        

            Else

              This.Nodes.Add(node,4,cNodeKey(i,1),"回收站",8)        

         Endif

      Else  

         cNodeKey(i,2)=.f.

   Endif

Endfor    

node.Sorted=.t.    &&将加入的文件夹列表排序

*/以下同样是为了判断文件夹是否含有子文件夹,如有,将第一个加入作为子节点

For i=1 To nWjs_father

       If cNodeKey(i,2)=.f.

           Loop

       Endif

       nWjs_Child=Adir(aWj_Child,cNodeKey(i,1)+"*.*",This.Parent.cWjjsx)

       For j=1 To nWjs_Child

           If left(aWj_Child(j,1),1)="."

               Loop

           Endif  

           If "D"$aWj_child(j,5)

              cNodeKey_child=cNodeKey(i,1)+aWj_child(j,1)

              This.Nodes.Add(cNodeKey(i,1),4,cNodeKey_child,"")

              Exit

           Endif

       Endfor      

Endfor        

This.getvisiblecount     &&此句必须要,这样能避免在列表的最下端展开节点却看不见任何子节点

 

在Ole1的Nodeclick中加入代码:

*** ActiveX 控件事件 ***

LPARAMETERS node

*/如果选定了根节点,将Seleml置空,否则置为指定的文件夹

If node.Key<>"我的电脑"

    This.parent.Seleml=Alltrim(node.Key)

  Else

    This.parent.Seleml=Space(1)

Endif

 

Ok,现在可以保存类,加入表单看看,是不是还有点专业的味?!

 

请大家注意,如果将这两个可视类加入你的应用程序,别忘了在制作安装盘时将MSComctl.ocx文件加入安装程序,安装或者拷到Windows的system文件夹中。

此主题相关图片如下:





 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值