ShellFileOperation() - Basic Wrapper

A shell function that can be called to Copy / Move / Delete / Rename File(s). Displays an animated progress bar if the task is time consuming. Progress bar is useful when operating on slower media like Digital Cameras or when dealing with huge files like video.
I have wrapped only the basic functionality. Hopefully, I should be updating it in near future. For customised needs refer MSDN.



Parameters:

The first parameter can be only one of the following:
Code:
FO_MOVE   := 0x1
FO_COPY   := 0x2
FO_DELETE := 0x3
FO_RENAME := 0x4


The Second / Third parameters should be strings containing path to Source and Destination
Source may contain Wildcards but not Target
Source can be a list of files delimited with pipe. ( The wrapper function replaces pipe characters with NULL )
Always use fullpath and not relative.

The fouth parameter can contain a combination of values for which please refer MSDN

Usage Examples:

Code:
ShellFileOperation( 0x2, A_AhkPath, A_DeskTop )                     ; Copy a Single file
ShellFileOperation( 0x2, "C:\Program Files\AutoHotkey", A_DeskTop ) ; Copy the whole folder


Advanced Example: ( Along with the wrapped Shell Function )

The following code performs a recursive scan on the Temporary Internet Files folder and creates a pipe delimited list of .gif files and passes it to the wrapper function which copies the files to the script's subfolder named Gif_Files.

Code (Expand):
SetBatchLines -1
SetWorkingDir, %A_ScriptDir%

imgPath := A_Temp . "orary Internet Files"
Loop, %imgPath%\*.gif, 0 ,1
     Source .= A_LoopFileLongPath "|"

Target := A_ScriptDir "\Gif_Files"

flags := ( FOF_RENAMEONCOLLISION := 0x8 ) | ( FOF_NOCONFIRMMKDIR := 0x200 )

ShellFileOperation( 0x2, Source, Target, flags )

Return



ShellFileOperation( fileO=0x0, fSource="", fTarget="", flags=0x0, ghwnd=0x0 )     {

 If ( SubStr(fSource,0) != "|" )
      fSource := fSource . "|"

 If ( SubStr(fTarget,0) != "|" )
      fTarget := fTarget . "|"

 fsPtr := &fSource
 Loop, % StrLen(fSource)
  If ( *(fsPtr+(A_Index-1)) = 124 )
      DllCall( "RtlFillMemory", UInt, fsPtr+(A_Index-1), Int,1, UChar,0 )

 ftPtr := &fTarget
 Loop, % StrLen(fTarget)
  If ( *(ftPtr+(A_Index-1)) = 124 )
      DllCall( "RtlFillMemory", UInt, ftPtr+(A_Index-1), Int,1, UChar,0 )

 VarSetCapacity( SHFILEOPSTRUCT, 30, 0 )                 ; Encoding SHFILEOPSTRUCT
 NextOffset := NumPut( ghwnd, &SHFILEOPSTRUCT )          ; hWnd of calling GUI
 NextOffset := NumPut( fileO, NextOffset+0    )          ; File operation
 NextOffset := NumPut( fsPtr, NextOffset+0    )          ; Source file / pattern
 NextOffset := NumPut( ftPtr, NextOffset+0    )          ; Target file / folder
 NextOffset := NumPut( flags, NextOffset+0, 0, "Short" ) ; options

 DllCall( "Shell32\SHFileOperationA", UInt,&SHFILEOPSTRUCT )
 
Return NumGet( NextOffset+0 )
}


The flag FOF_NOCONFIRMMKDIR supresses the user confirmation for subfolder creation and FOF_RENAMEONCOLLISION takes care of renaming similar filenames.

FOF_RENAMEONCOLLISION: For example I recursively scanned for README.TXT in drive C: and I had a list of 667 files. When copied to the same folder with FOF_RENAMEONCOLLISION, The 1st file was README.TXT, 2nd file was Copy of README.TXT, 3rd file was Copy (1) of README.TXT ... and the last file was Copy (665) of README.TXT

Note: You see a progress bar only if the above takes more than a couple of seconds