|
|
![]() |
|
||
|
|
|||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||
| Visual Basic Win32 Shell Routines SHFileOperation: Copy or Move an Entire Directory |
||
| Posted: | Sunday January 26, 1997 | |
| Updated: | Monday December 26, 2011 | |
| Applies to: | VB4-32, VB5, VB6 | |
| Developed with: | VB4-32, Windows 95 | |
| OS restrictions: | None | |
| Author: | VBnet - Randy Birch | |
|
Related: |
SHFileOperation: Add Recycle Bin Functionality SHFileOperation: Copy, Move or Delete Files SHQueryRecycleBin: Recycle Bin Management |
|
| Prerequisites |
| None. |
|
|
As
shown in SHFileOperation: Add Recycle Bin Functionality
and SHFileOperation: Copy, Move or Delete Files,
Windows offers the option of sending files to the recycle bin using the SHFileOperation API. However, this same API can also be used to copy
individual files, or, as detailed below, to copy or move an entire folder and its contents, including subfolders, to a new destination.It must be noted up front that the following code, for simplicity, does not provide for any checking of the validity of the source or destinations entered, nor does it distinguish between a folder and a drive. Therefore, use caution, or you could accidentally copy drive C:\ into a folder!!
|
| BAS Module Code |
| None. |
|
|
| Form Code |
|
|
Start a new project and to
a new form add:
Set the Locked property (VB5/VB6 only) for both text boxes to True, and set the control captions as indicated in the illustration. Finish the form off by adding labels. The frames used in the example are optional. Add the following to the form: |
|
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Private Type SHFILEOPSTRUCT
hWnd As Long
wFunc As Long
pFrom As String
pTo As String
fFlags As Integer
fAborted As Boolean
hNameMaps As Long
sProgress As String
End Type
Private Const FO_MOVE As Long = &H1
Private Const FO_COPY As Long = &H2
Private Const FO_DELETE As Long = &H3
Private Const FO_RENAME As Long = &H4
Private Const FOF_SILENT As Long = &H4
Private Const FOF_RENAMEONCOLLISION As Long = &H8
Private Const FOF_NOCONFIRMATION As Long = &H10
Private Const FOF_SIMPLEPROGRESS As Long = &H100
Private Const FOF_ALLOWUNDO As Long = &H40
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" _
(ByVal nSize As Long, ByVal lpBuffer As String) As Long
Private Declare Function SHFileOperation Lib "shell32" _
Alias "SHFileOperationA" _
(lpFileOp As SHFILEOPSTRUCT) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32" _
Alias "SHGetPathFromIDListA" _
(ByVal pidl As Long, ByVal pszPath As String) As Long
Private Declare Function SHGetSpecialFolderLocation Lib "shell32" _
(ByVal hwndOwner As Long, _
ByVal nFolder As Long, _
pidl As Long) As Long
Private Declare Function SHBrowseForFolder Lib "shell32" _
Alias "SHBrowseForFolderA" _
(lpBrowseInfo As BROWSEINFO) As Long
Private Type BROWSEINFO
hOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
Private Const ERROR_SUCCESS As Long = 0
Private Const CSIDL_DESKTOP As Long = &H0
Private Const BIF_RETURNONLYFSDIRS As Long = &H1
Private Const BIF_STATUSTEXT As Long = &H4
Private Const BIF_RETURNFSANCESTORS As Long = &H8
'FO_FUNC - the File Operation to perform,
'determined by the type of SHFileOperation
'action chosen (move/copy)
Dim FO_FUNC As Long
'for ease of reading, constants are substituted
'for SHFileOperation numbers in code
Const FileMove As Integer = 1
Const FileCopy As Integer = 2
'Check button index constants
Const optSilent As Integer = 0
Const optNoFilenames As Integer = 1
Const optNoConfirmDialog As Integer = 2
Const optRenameIfExists As Integer = 3
Const optPromptMeFirst As Integer = 4
'strings to hold paths for this demo
Dim source As String
Dim destination As String
Private Sub Form_Load()
Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
Option1(FileCopy).Value = True
Command1(0).Caption = "Select Source"
Command1(1).Caption = "Select Target"
Command2.Caption = "Perform Action"
Command3.Caption = "End"
Option1(1).Caption = "Move Source Folder to Destination"
Option1(2).Caption = "Copy Source Folder to Destination"
Check1(0).Caption = "Don't show operation (no copy dialog)"
Check1(1).Caption = "Don't show filenames for multiple deletes"
Check1(2).Caption = "Don't prompt for confirmation"
Check1(3).Caption = "Rename file if target name already exists"
Check1(4).Caption = "Whoa !! Prompt me before doing it !"
End Sub
Private Sub Command1_Click(Index As Integer)
Dim tmp As String
Select Case Index
Case 0:
tmp = GetBrowseFolder("Select the SOURCE to move or copy:")
If Len(tmp) > 0 Then
source = tmp
Text1.Text = source
End If
Case 1:
tmp = GetBrowseFolder("Select the folder DESTINATION:")
If Len(tmp) > 0 Then
destination = tmp
Text2.Text = destination
End If
End Select
End Sub
Private Sub Command2_Click()
Dim msg As String
Dim action As Boolean
'First, assume the user WILL want to perform the
'action, in case they don't want prompting
action = True
'check if they've asked to be prompted about the action...
If Check1(optPromptMeFirst).Value = 1 Then
msg = "You have chosen to move or copy the folder and contents of :" & vbCrLf
msg = msg & source & vbCrLf & vbCrLf
msg = msg & "to the destination:" & vbCrLf
msg = msg & destination & vbCrLf & vbCrLf
msg = msg & "Are you sure that you want to proceed with this action?"
'since they want to be prompted, set the action
'based on their response to a messagebox.
'
'Two buttons are presented - Yes and No.
'
'If No is selected, the the return value from the
'messagebox is vbNo. When that is compared with
'vbYes in the expression, the result is FALSE, therefore
'the action variable will be set to false.
'
'If Yes is selected, the the return value from the
'messagebox is vbYes, which equals vbYes, therefore
'the expression will return TRUE to the action variable
action = MsgBox(msg, vbExclamation Or vbYesNo, "Warning") = vbYes
End If
If action = True Then
PerformShellAction source, destination
End If
End Sub
Private Sub Command3_Click()
Unload Me
End Sub
Private Sub Option1_Click(Index As Integer)
'set the file action flag
FO_FUNC = CLng(Index)
End Sub
Public Function PerformShellAction(sSource As String, _
sDestination As String) As Long
Dim FOF_FLAGS As Long
Dim SHFileOp As SHFILEOPSTRUCT
'terminate the folder string with a pair of nulls
sSource = sSource & Chr$(0) & Chr$(0)
'determine the user's options selected
FOF_FLAGS = BuildBrowseFlags()
'set up the options
With SHFileOp
.wFunc = FO_FUNC
.pFrom = sSource
.pTo = sDestination
.fFlags = FOF_FLAGS
End With
'and perform the chosen copy or move operation
PerformShellAction = SHFileOperation(SHFileOp)
End Function
Private Function BuildBrowseFlags() As Long
'Iterate through the options, and build
'the flag variable according to the user selection.
Dim flag As Long
'these can be multiple
If Check1(optSilent).Value Then flag = flag Or FOF_SILENT
If Check1(optNoFilenames).Value Then flag = flag Or FOF_SIMPLEPROGRESS
If Check1(optNoConfirmDialog).Value Then flag = flag Or FOF_NOCONFIRMATION
If Check1(optRenameIfExists).Value Then flag = flag Or FOF_RENAMEONCOLLISION
BuildBrowseFlags = flag
End Function
Private Function GetBrowseFolder(msg) As String
Dim pidl As Long
Dim pos As Integer
Dim path As String
Dim bi As BROWSEINFO
'Fill the BROWSEINFO structure with the needed data,
'show the browse dialog, and if the returned value
'indicates success (1), retrieve the user's
'selection contained in pidl
With bi
.hOwner = Me.hWnd
.pidlRoot = CSIDL_DESKTOP
.lpszTitle = msg
.ulFlags = BIF_RETURNONLYFSDIRS
End With
pidl = SHBrowseForFolder(bi)
path = Space$(512)
If SHGetPathFromIDList(ByVal pidl, ByVal path) = 1 Then
pos = InStr(path, Chr$(0))
GetBrowseFolder = Left(path, pos - 1)
End If
End Function |
| Comments |
Run
the project and select both a source folder (the folder to copy or move) and a destination for it. The destination can be another folder on
the same drive, on a different drive, or the drive root. Select a move or copy action, and any of the options you would
like to test. Selecting the item "Rename the file if it already exists" will perform the action and create a new folder with the
prefix "Copy of" should a folder of the same name already exists.
The code in the Command2_Click sub checks to see whether the "Prompt before doing it" check button has been selected. If it has (recommended), a messagebox pops up providing a last-chance to abort the procedure.
|
|
|
|
|
|
|||||
|
|||||
|
|
|||||
|
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |
![]() |