在VFP中获取磁盘结构信息
软件世界
在编程时我们经常会需要得到系统中可用磁盘的一些信息,在Visual FoxPro中可用DiskSpace()、Sys(2022)得到剩余空间和簇大小,但如果要得到磁盘组织的一些信息如卷标、序列号等,这些信息直接使用VFP提供的函数显然是无法得到的。本文介绍如何访问动态链接库,使用DLL函数GetLogicalDriverStrings、GetDriveType、GetVolumeInformation和GetDiskFreeSpace,来获得磁盘组织的重要信息,以便在文件创建、软件注册时加以应用。
GetLogicalDriverStrings用于获取可用磁盘机代码(盘符),包括硬盘的逻辑分区;GetDriveType用以获得磁盘类型,是软驱、硬盘、网络驱动器、CDROM还是RAM虚拟盘;GetVolumeInformation用以获取包括磁盘卷标、序列号、文件名每个部分如路径中“\”与“\”之间部分的最大长度、文件系统的某些特性等与磁盘卷有关的信息;GetDiskFreeSpace函数用于获取磁盘上每簇扇区数、每扇区字节数、剩余簇数、总簇数等与磁盘组织有关的信息。这四个函数均包含在%SystemRoot%\System32\Kernel32.dll中,在调用时,先用DECLARE命令注册DLL函数,并指定参数的数目和类型,也可以在参数前添加“@”来强制参数按引用传递。函数的名称要区分大小写,并指定WIN32API为库名称,则Visual FoxPro将到Kernel32.dll中自动查找被调用的32位Windows DLL函数。运行TEST表单即可扫描当前系统上所有可用盘符,并出现在盘符下拉框中。下面介绍其主要实现方法。
一、创建表单并在Form的Activate过程中添加代码
添加的代码如下:
* 获得当前系统上所有可用磁盘机代码,并作为Form中盘符组合框的数值。
PUBLIC sAllDrivers, sAvaiDsk
DECLARE INTEGER GetLogicalDriveStrings IN Win32api AS GetLogDsk INTEGER nBufferLength, STRING lpBuffer
IngRetVal=0
sAllDrivers = SPACE(128) &&获得所有可用磁盘机代码
lngRetVal = GetLogDsk(LEN(sAllDrivers), @sAllDrivers)
CLEAR DLLS
sAllDrivers=TRIM(sAllDrivers)
** sAllDrivers="A:\ B:\ C:\……",盘符之间原用chr(0)分隔的,改用“,”间隔。sAllDrivers=CHRTRAN(sAllDrivers,CHR(0),",")
THISFORM.sAllDsk.VALUE=sAllDrivers
THISFORM.combo1.ADDITEM(sAllDrivers) && 将可用盘符添加到combo1的选项中.
* 在此可将不同磁盘类型对应的图标(或位图)添加到盘符组合框combo1.picture属性中,可见带图标的组合下拉框列表,代码从略。
二、在盘符组合框combo1的Click中添加代码
要在盘符下拉框中选择任一可用盘,立即显示其结构信息。在盘符组合框combo1的Click中添加代码如下:
strDrive=TRIM(THISFORM.combo1.VALUE)+"\"
DECLARE INTEGER GetDriveType IN win32api AS GetDrType STRING nDrive
DIMENSION DskType(5) && 下面判断磁盘类型
Dsktype(1)="软盘" && GetDrType(strDrive)=2
Dsktype(2)="硬盘" && GetDrType(strDrive)=3
Dsktype(3)="网络驱动器" && GetDrType(strDrive)=4
Dsktype(4)="CDROM" && GetDrType(strDrive)=5
Dsktype(5)="RAM虚拟驱动器" && GetDrType(strDrive)=6
THISFORM.text2.VALUE=DskType(GetDrType(strDrive)-1)
**取得磁盘卷信息
DECLARE INTEGER GetVolumeInformation IN Win32api AS GetVolInfo ;
STRING lpRootPathName,STRING lpVolumeNameBuffer,INTEGER nVolumeNameSize,;
INTEGER @lpVolumeSerialNumber, INTEGER @lpMaximumComponentLength,;
INTEGER @lpFileSystemFlags,STRING lpFileSystemNameBuffer,;
INTEGER nFileSystemNameSize
STORE 0 TO VolSerialNum,MaxComLen,FSysFlag,IngRetVal
VolLabel = REPLACE(CHR(0),255)
FSysNameBuf= REPLACE(CHR(0),255)
IngRetVal = GetVolInfo (strDrive, @VolLabel, LEN(VolLabel), @VolSerialNum, @MaxComLen, @FSysFlag, @FSysNameBuf, LEN(FsysNameBuf) )
THISFORM.text3.VALUE=TRIM(VolLabel) &&磁盘卷标
THISFORM.text4.VALUE= VolSerialNum &&磁盘序列号
THISFORM.text5.VALUE=TRIM(FSysNameBuf) &&文件系统FAT FAT32 NTFS CDFS等
THISFORM.text7.VALUE= MaxComLen &&文件名成分长度
* 判断文件系统名称及卷特性thisform.text6.value
* FSysFlag装载了一个或多个二进制位标志,以下是这些标志位的意义。
FS_Case_Is_Preserved=0x0002 &&文件名的大小写保持写入时的状态
FS_Case_Sensitive=0x0001 &&文件名中要区别大小写
FS_Unicode_Stor_On_Disk=0x0004 &&文件名支持为Unicode格式
FS_Persistent_ACLS=0x0008 &&文件系统支持访问控制列表(ACL)安全机制
FS_File_Compression=0x0010 &&文件系统支持逐文件地进行文件压缩
FS_Vol_Is_Preserved=0x8000 &&整个磁盘卷都是压缩的
FSysFtmp=""
FSysFtmp=iif(bitand(FSysFlag,FS_Case_Is_Preserved)>0,FSysFtmp+"文件名的大小写保持写入时的状态"+chr(13),FSysFtmp)
FSysFtmp=iif(bitand(FSysFlag,FS_Case_Sensitive)>0,FSysFtmp+"文件名中要区别大小写"+chr(13),FSysFtmp)
FSysFtmp=iif(bitand(FSysFlag,FS_Unicode_Stor_On_Disk)>0,FSysFtmp+"文件名支持为Unicode格式"+chr(13),FSysFtmp)
FSysFtmp=iif(bitand(FSysFlag,FS_Persistent_ACLS)>0,FSysFtmp+"文件系统支持ACL安全机制"+chr(13),FSysFtmp)
FSysFtmp=iif(bitand(FSysFlag,FS_File_Compression)>0,FSysFtmp+"文件系统支持逐文件地进行文件压缩"+chr(13),FSysFtmp)
FSysFtmp=iif(bitand(FSysFlag,FS_Vol_Is_Preserved)>0,FSysFtmp+"整个磁盘卷都是压缩的"+chr(13),FSysFtmp)
THISFORM.text6.VALUE=FSysFtmp
* 获取磁盘组织信息
DECLARE INTEGER GetDiskFreeSpace IN Win32api;
STRING lpRootPathName,INTEGER @lpSectorsPerCluster,;
INTEGER @lpBytesPerSector,INTEGER @lpNumberOfFreeClusters,;
INTEGER @lpTtoalNumberOfClusters
STORE 0 TO SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalClusters
INGRETVAL = GetDiskFreeSpace(strDrive, @SectorsPerCluster, @BytesPerSector, @NumberOfFreeClusters, @TotalClusters)
IF INGRETVAL <> 0
THISFORM.text8.VALUE=SectorsPercluster
THISFORM.text9.VALUE=BytesPerSector
THISFORM.text10.VALUE=NumberofFreeClusters
THISFORM.text11.VALUE=Totalclusters
THISFORM.DskFreeSpace.VALUE= SectorsPerCluster * BytesPerSector * NumberOfFreeClusters && 磁盘剩余空间
THISFORM.DskTotalSpace.VALUE = SectorsPerCluster * BytesPerSector *TotalClusters ** 磁盘总空间
ENDIF
本文在Visual FoxPro6.0、Windows98/2000/NT/XP 均运行通过。