回 帖 发 新 帖 刷新版面

主题:如何在FSO拷贝文件中使用进度条

我是用FileSystemObject(FSO)将一个文件夹拷贝到另一个文件夹,我想问如何在工程中使用ProgressBar显示进度。谢谢。

回复列表 (共13个回复)

沙发

如果你是将该文件夹下的所有文件一个个复制到另一个文件夹,可先用FSO获取文件数量的方法取得该文件夹下的文件数,把进度条最大值设为此数,然后在For循环中复制,每复制一个文件,进度条的当前值+1

板凳

一江秋水的方法不行.即使成立,复制过程中也会"一顿一顿"的,更何况不成立.事实上,拷文件A后拷文件B之前,界面是来不及反映PROCESSBAR改进度的,虽然你写了让它改变状态的代码.相反的,呈现出一种"假死状态".(你可以用较大的文件来测试,如10M的文件).
要想达到这种效果,可以采用二进制来读写文件的方式,并且让此工作在独立线程中进行,然后在每拷贝一些字节后就向程序界面窗口发送消息使其改变进度条进度.这样做是为了让"界面线程和工作线程分开".才能达到效果.

3 楼

你没试怎么知道不行?实践是检验真理的唯一标准。下面以复制txt文件为例:

Private Sub Command1_Click()
Dim fs, fo
Dim j As Integer, Path1 As String, Path2 As String, fName As String
Path1 = "(被复制文件夹路径)"
Path2 = "(复制到文件夹路径)"
Set fs = CreateObject("Scripting.FileSystemObject")
Set fo = fs.GetFolder(Path1)
j = Val(fo.Files.Count)
Set fs = Nothing
ProgressBar1.Max = j
fName = Dir(Path1 & "*.txt")
Do While Len(fName)
  FileCopy Path1 & fName, Path2 & fName
  ProgressBar1.Value = ProgressBar1.Value + 1
  DoEvents
  fName = Dir
Loop
End Sub

用你说的方法未免太复杂,你装微软的WINDOWS操作系统时,系统要先复制文件,也是按文件数量来改变进度的,复制一个CAB类型的文件时,进度条不也是停止在53%上好久?再说了,你有几个10M的文件呢?

4 楼

一江秋水的方法简单一行,被广泛采用。
还有类似的,不用文件数作计量标准,而采用文件大小做标准的。
还有,重新计算当前进度的时机,还有一“页”完成时的。
当然这些都代码复杂。

5 楼

还是按文件个数来表识进度条比较容易实现 而且也比较实用
同意 一江秋水

6 楼

嗯.我是实践过才发言的啊.因为以前也做过此类事情.效果确实不理想.(做资源释放的).
一江秋水的方法也不错.赞成.

7 楼

用一个全局变量I来表示文件操作进度值,用timer来检查I的值,并改写进度条的值,即可解决进度条比较卡的问题。

8 楼

例如从A目录拷贝到B目录,可不可以用进度条ProgressBar来显示A目录的大小

9 楼

恳请各位高手指点一下,顺祝清明节快乐.

10 楼

'用这段代码即可实现上述功能,进度窗口需自己建一个,具体功能你自己定义
'这些常量规定了复制共间的具体操作行为
Public Const PROGRESS_CANCEL = 1          '取消这次复制(可重新启动)       
Public Const PROGRESS_CONTINUE = 0        '如未完成继续进行复制  
Private Const PROGRESS_QUIET = 3          '退出这次复制(不可重新启动)  
Public Const PROGRESS_STOP = 2            '停止复制
Private Const COPY_FILE_FAIL_IF_EXISTS = &H1       
Private Const COPY_FILE_RESTARTABLE = &H2          

'// 此 API 在 WIN9X 下不能使用
Private Declare Function CopyFileEx Lib "kernel32.dll" Alias "CopyFileExA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal lpProgressRoutine As Long, lpData As Any, ByRef PBCancel As Long, ByVal dwCopyFlags As Long) As Long

Private mlngCancel                  As Long
Private mprgState                   As Object
Private mlblState                   As Object
Public lReturnValue As Long         '复制行为变量,可在复制期间改变做为回调函数的返回值,根据此返回值API函数决定要进行什么操作

’下面的函数为COPYFILEEX函数的回调函数
Public Function CopyProgressRoutine(ByVal TotalFileSize As Currency, _
                                    ByVal TotalBytesTransferred As Currency, _
                                    ByVal StreamSize As Currency, _
                                    ByVal StreamBytesTransferred As Currency, _
                                    ByVal dwStreamNumber As Long, _
                                    ByVal dwCallbackReason As Long, _
                                    ByVal hSourceFile As Long, _
                                    ByVal hDestinationFile As Long, _
                                    ByVal lpData As Long) As Long
   '// 显示进度
   mprgState.Value = CLng((100 / TotalFileSize) * TotalBytesTransferred)
  ' mlblState.Caption = "已完成: " & FormatPercent(mprgState.Value / 100, 0)
   '
   DoEvents
   '// 继续复制
   CopyProgressRoutine = lReturnValue
End Function

'************************************************
'** 函数名称:  uCopyFile
'** 函数功能:  复制文件
'** 参数说明:
'**            strFrom              源文件
'**            strTo                目标文件
'**            prgState             进度条控件
'**            lblState             用来显示进度的 Label
'** 函数返回:
'**            Boolean 类型
'**            True                 复制成功
'**            False                复制失败
'** 参考实例:
'**
'**            blnReturn = uCopyFile("c:\test.exe", "d:\test.exe", prgState, lblState)
'************************************************
Public Function uCopyFile(ByVal strFrom As String, _
                          ByVal strTo As String, _
                          ByRef prgState As Object) As Boolean
   Dim lngReturn                   As Long
   
   Set mprgState = prgState
  ' Set mlblState = lblState
   '// 开始复制
   lngReturn = CopyFileEx(strFrom, strTo, _
                          AddressOf CopyProgressRoutine, ByVal 0&, mlngCancel, COPY_FILE_RESTARTABLE)

   If lngReturn = 0 Then
      uCopyFile = False
   Else
      uCopyFile = True
   End If
End Function

'注:prgState为窗体中的一个PROGRESSBAR控件

我来回复

您尚未登录,请登录后再回复。点此登录或注册