VB與Windows資源管理員互拷檔案

來源:互聯網
上載者:User

VB與Windows資源管理員互拷檔案
    通過VB編程來拷貝或移動檔案的原理可能大家都十分清楚,可以利用Windows API
SHFileOperation來進行操作,也可以利用VB內建的函數來操作。但是利用這些方法編
寫的程式只能在程式內部執行檔案的操作。這裡我要向大家介紹如何通過VB編程將程式
中的檔案操作同Windows的資源管理員中的拷貝、剪下操作串連起來。
    在Windows的資源管理員中,選中一個或多個檔案,在檔案上單擊滑鼠右鍵,在彈
出菜單中選複製。再切換到另外的目錄,單擊滑鼠右鍵,點粘貼。就執行了一次檔案的
拷貝操作,那麼Windows在拷貝過程中執行了什麼操作,是否將整個檔案拷貝到剪貼版
上了呢?當然沒有。實際上,windows只是將一個檔案結構拷貝到了剪貼版,這個結構
如下:
    tDropFile+檔案1檔案名稱+vbNullChar檔案2檔案名稱+vbNullChar...+檔案N檔案名稱+vbNullChar
其中tDropFile是一個DROPFILES結構,這個結構在Windows API中有定義。在粘貼檔案
時,利用API函數 DragQueryFile 就可以獲得拷貝到剪貼版的檔案全路徑名,然後就
可以根據獲得的檔案名稱執行檔案拷貝函數,實現對檔案的粘貼操作。
    下面通過具體的程式來介紹:
    1、在工程檔案中加入一個Module,然後在Module中加入如下代碼:
Option Explicit

Private Type POINTAPI
   x As Long
   y As Long
End Type

Private Type SHFILEOPSTRUCT
    hwnd As Long
    wFunc As Long
    pFrom As String
    pTo As String
    fFlags As Integer
    fAnyOperationsAborted As Long
    hNameMappings As Long
    lpszProgressTitle As String
End Type

Private Declare Function SHFileOperation Lib "shell32.dll" Alias _
        "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

'剪貼版處理函數
Private Declare Function EmptyClipboard Lib "user32" () As Long
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd _
        As Long) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function SetClipboardData Lib "user32" (ByVal wFormat _
        As Long, ByVal hMem As Long) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat _
        As Long) As Long
Private Declare Function IsClipboardFormatAvailable Lib "user32" _
        (ByVal wFormat As Long) As Long

Private Declare Function DragQueryFile Lib "shell32.dll" Alias _
        "DragQueryFileA" (ByVal hDrop As Long, ByVal UINT As Long, _
        ByVal lpStr As String, ByVal ch As Long) As Long
Private Declare Function DragQueryPoint Lib "shell32.dll" (ByVal _
        hDrop As Long, lpPoint As POINTAPI) As Long
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags _
        As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As _
        Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As _
        Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As _
        Long) As Long
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" _
        (Destination As Any, Source As Any, ByVal Length As Long)

'剪貼版資料格式定義
Private Const CF_TEXT = 1
Private Const CF_BITMAP = 2
Private Const CF_METAFILEPICT = 3
Private Const CF_SYLK = 4
Private Const CF_DIF = 5
Private Const CF_TIFF = 6
Private Const CF_OEMTEXT = 7
Private Const CF_DIB = 8
Private Const CF_PALETTE = 9
Private Const CF_PENDATA = 10
Private Const CF_RIFF = 11
Private Const CF_WAVE = 12
Private Const CF_UNICODETEXT = 13
Private Const CF_ENHMETAFILE = 14
Private Const CF_HDROP = 15
Private Const CF_LOCALE = 16
Private Const CF_MAX = 17

' 記憶體操作定義
Private Const GMEM_FIXED = &H0
Private Const GMEM_MOVEABLE = &H2
Private Const GMEM_NOCOMPACT = &H10
Private Const GMEM_NODISCARD = &H20
Private Const GMEM_ZEROINIT = &H40
Private Const GMEM_MODIFY = &H80
Private Const GMEM_DISCARDABLE = &H100
Private Const GMEM_NOT_BANKED = &H1000
Private Const GMEM_SHARE = &H2000
Private Const GMEM_DDESHARE = &H2000
Private Const GMEM_NOTIFY = &H4000
Private Const GMEM_LOWER = GMEM_NOT_BANKED
Private Const GMEM_VALID_FLAGS = &H7F72
Private Const GMEM_INVALID_HANDLE = &H8000
Private Const GHND = (GMEM_MOVEABLE Or GMEM_ZEROINIT)
Private Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)

Private Const FO_COPY = &H2

Private Type DROPFILES
   pFiles As Long
   pt As POINTAPI
   fNC As Long
   fWide As Long
End Type

Public Function clipCopyFiles(Files() As String) As Boolean
   Dim data As String
   Dim df As DROPFILES
   Dim hGlobal As Long
   Dim lpGlobal As Long
   Dim i As Long
  
   '清除剪貼版中現存的資料
   If OpenClipboard(0&) Then
        Call EmptyClipboard
     
        For i = LBound(Files) To UBound(Files)
            data = data & Files(i) & vbNullChar
        Next i
        data = data & vbNullChar

        '為剪貼版拷貝操作分配相應大小的記憶體
        hGlobal = GlobalAlloc(GHND, Len(df) + Len(data))
        If hGlobal Then
            lpGlobal = GlobalLock(hGlobal)
        
            df.pFiles = Len(df)
     '將DropFiles結構拷貝到記憶體中
            Call CopyMem(ByVal lpGlobal, df, Len(df))
     '將檔案全路徑名拷貝到分配的記憶體中。
            Call CopyMem(ByVal (lpGlobal + Len(df)), ByVal data, _
                Len(data))
            Call GlobalUnlock(hGlobal)
        
            '將資料拷貝到剪貼版上
     If SetClipboardData(CF_HDROP, hGlobal) Then
                clipCopyFiles = True
            End If
        End If
        Call CloseClipboard
    End If
End Function

Public Function clipPasteFiles(Files() As String) As Long
   Dim hDrop As Long
   Dim nFiles As Long
   Dim i As Long
   Dim desc As String
   Dim filename As String
   Dim pt As POINTAPI
   Dim tfStr As SHFILEOPSTRUCT
   Const MAX_PATH As Long = 260
  
   '確定剪貼版的資料格式是檔案,並開啟剪貼版
   If IsClipboardFormatAvailable(CF_HDROP) Then
        If OpenClipboard(0&) Then
            hDrop = GetClipboardData(CF_HDROP)
            '獲得檔案數
            nFiles = DragQueryFile(hDrop, -1&, "", 0)
     
            ReDim Files(0 To nFiles - 1) As String
            filename = Space(MAX_PATH)
        
            '確定執行的操作類型為拷貝操作
     tfStr.wFunc = FO_COPY
     '目的路徑設定為File1指定的路徑
            tfStr.pTo = Form1.File1.Path
        
            For i = 0 To nFiles - 1
  '根據擷取的每一個檔案執行檔案拷貝操作
                Call DragQueryFile(hDrop, i, filename, Len(filename))
                Files(i) = TrimNull(filename)
                tfStr.pFrom = Files(i)
                SHFileOperation tfStr
            Next i
            Form1.File1.Refresh
            Form1.Dir1.Refresh
        
            Call CloseClipboard
        End If
        clipPasteFiles = nFiles
    End If
End Function

Private Function TrimNull(ByVal StrIn As String) As String
   Dim nul As Long
  
   nul = InStr(StrIn, vbNullChar)
   Select Case nul
      Case Is > 1
         TrimNull = Left(StrIn, nul - 1)
      Case 1
         TrimNull = ""
      Case 0
         TrimNull = Trim(StrIn)
   End Select
End Function

    2、在Form1中加入一個FileListBox,Name屬性設定為File1。加入一個DirListBox,
Name屬性設定為Dir1,在Dir1的Change事件中加入如下代碼:
Private Sub Dir1_Change()
   File1.Path = Dir1.Path
End Sub
加入一個DriveListBox,Name屬性設定為Drive1,在Drive1的Change事件中加入如下
代碼:
Private Sub Drive1_Change()
   Dir1.Path = Drive1.Drive
End Sub
加入一個CommandButton,Name屬性設定為cmdCopy,在cmdCopy的Click事件中加入如下
代碼:
Private Sub cmdCopy_Click()
   Dim Files() As String
   Dim Path As String
   Dim i As Long, n As Long
  
   Path = Dir1.Path
   If Right(Path, 1) <> "/" Then
      Path = Path & "/"
   End If
  
   '根據在List1上的選擇建立拷貝檔案的列表
   With File1
      For i = 0 To .ListCount - 1
         If .Selected(i) Then
            ReDim Preserve Files(0 To n) As String
            Files(n) = Path & .List(i)
            n = n + 1
         End If
      Next i
   End With
  
   '拷貝檔案到Clipboard
   If clipCopyFiles(Files) Then
      MsgBox "拷貝檔案成功.", , "Success"
   Else
      MsgBox "無法拷貝檔案...", , "Failure"
   End If
End Sub
加入一個CommandButton,Name屬性設定為cmdPaste,在cmdPaste的Click事件中加入如
下代碼:
Private Sub cmdPaste_Click()
   Dim Files() As String
   Dim nRet As Long
   Dim i As Long
   Dim msg As String
  
   nRet = clipPasteFiles(Files)
   If nRet Then
      For i = 0 To nRet - 1
         msg = msg & Files(i) & vbCrLf
      Next i
      MsgBox msg, , "共粘貼" & nRet & "個檔案"
   Else
      MsgBox "從剪貼版粘貼檔案錯誤", , "Failure"
   End If
End Sub

    運行檔案,在Windows 資源管理員中,選擇檔案,再在資源管理員菜單中選 編輯 | 複製
然後在Form1中點擊cmdPaste,從資源管理員中複製的檔案就拷貝到Dir1所在的目錄中。從
File1中選擇檔案,按cmdCopy複製,再在資源管理員中選 編輯 | 粘貼 ,選擇的檔案就被
拷貝到Windows 資源管理員的目前的目錄下。
    上面的程式在Windows98 VB6.0下運行通過。

www.applevb.com

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.