天天看點

磁盤分區清單和檔案夾清單(treeview應用) 類似資料總管

磁盤分區清單和檔案夾清單(treeview應用) 類似資料總管
此主題相關圖檔如下:
磁盤分區清單和檔案夾清單(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張圖示,依次代表軟碟、軟碟、硬碟、網絡驅動器、CD光牒、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)='CD光牒'

           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步的圖示依次改為軟碟、硬碟、網絡驅動器、CD光牒、我的電腦、打開的檔案夾、關閉的檔案夾、資源回收筒。

将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)='CD光牒'

           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檔案夾中。

此主題相關圖檔如下:

繼續閱讀