Table of Contents

Multiple file operations

by Richard Russell, July 2007

The Windows API function SHFileOperation is very flexible, allowing you to perform common file-system operations (delete, copy, move/rename) on one or more files. It can optionally move 'deleted' files to the Recycle Bin, display a handy progress dialogue for lengthy operations and prompt for confirmation.

Initialisation


Before using the SHFileOperation API incorporate the following declarations in your program:

        FO_MOVE = 1
        FO_COPY = 2
        FO_DELETE = 3
        FOF_MULTIDESTFILES =  1
        FOF_CONFIRMMOUSE = 2
        FOF_SILENT = 4
        FOF_RENAMEONCOLLISION = 8
        FOF_NOCONFIRMATION = 16
        FOF_WANTMAPPINGHANDLE = 32
        FOF_ALLOWUNDO = 64
        FOF_FILESONLY = 128
        FOF_SIMPLEPROGRESS = 256 : REM shfo.fFlags.h& = 1
        FOF_NOCONFIRMMKDIR = 512 : REM shfo.fFlags.h& = 2

Deleting files


To delete one or more files use code similar to the following:

        DEF PROCdeletefiles(afsp$)
        LOCAL shfo{}
        DIM shfo{hWnd%, wFunc%, pFrom%, pTo%, fFlags{l&,h&}, \
        \        fAborted%, hNameMaps%, sProgress%}
        afsp$ += CHR$0 + CHR$0
        shfo.hWnd% = @hwnd%
        shfo.wFunc% = FO_DELETE
        shfo.pFrom% = PTR(afsp$)
        SYS "SHFileOperation", shfo{}
        ENDPROC

As shown the operation will display a progress dialogue and prompt the user for confirmation. If you prefer it to happen 'silently' initialise the fFlags member as follows:

        shfo.fFlags.l& = FOF_SILENT OR FOF_NOCONFIRMATION
        shfo.fFlags.h& = 0

You can specify that the files are moved to the Recycle Bin rather than permanently deleted as follows:

        shfo.fFlags.l& = FOF_ALLOWUNDO OR FOF_NOCONFIRMATION
        shfo.fFlags.h& = 0


Copying files


To copy one or more files use code similar to the following:

        DEF PROCcopyfiles(from$,dest$)
        LOCAL shfo{}
        DIM shfo{hWnd%, wFunc%, pFrom%, pTo%, fFlags{l&,h&}, \
        \        fAborted%, hNameMaps%, sProgress%}
        from$ += CHR$0 + CHR$0
        dest$ += CHR$0 + CHR$0
        shfo.hWnd% = @hwnd%
        shfo.wFunc% = FO_COPY
        shfo.pFrom% = PTR(from$)
        shfo.pTo% = PTR(dest$)
        SYS "SHFileOperation", shfo{}
        ENDPROC

The from$ parameter should contain one or more path/filenames separated by NULs (CHR$0); the filenames may include wildcard characters (? or *). The dest$ parameter should contain the path to the destination folder to which you want the files to be copied; this folder will be created if necessary.

As shown the operation will display a progress dialogue and prompt the user for confirmation. If you prefer it to happen 'silently' initialise the fFlags member as follows:

        shfo.fFlags.l& = FOF_SILENT OR FOF_NOCONFIRMATION
        shfo.fFlags.h& = FOF_NOCONFIRMMKDIR DIV 256

If you want to copy only files, rather than any subdirectories included in the from$ specification, add the “FOF_FILESONLY” flag.

Moving files


To move (or rename) one or more files use code similar to the following:

        DEF PROCmovefiles(from$,dest$)
        LOCAL shfo{}
        DIM shfo{hWnd%, wFunc%, pFrom%, pTo%, fFlags{l&,h&}, \
        \        fAborted%, hNameMaps%, sProgress%}
        from$ += CHR$0 + CHR$0
        dest$ += CHR$0 + CHR$0
        shfo.hWnd% = @hwnd%
        shfo.wFunc% = FO_MOVE
        shfo.pFrom% = PTR(from$)
        shfo.pTo% = PTR(dest$)
        SYS "SHFileOperation", shfo{}
        ENDPROC

The from$ parameter should contain one or more path/filenames separated by NULs (CHR$0); the filenames may include wildcard characters (? or *). The dest$ parameter should contain the path to the destination folder to which you want the files to be moved; this folder will be created if necessary.

As shown the operation will display a progress dialogue and prompt the user for confirmation. If you prefer it to happen 'silently' initialise the fFlags member as follows:

        shfo.fFlags.l& = FOF_SILENT OR FOF_NOCONFIRMATION
        shfo.fFlags.h& = FOF_NOCONFIRMMKDIR DIV 256

If you want to move only files, rather than any subdirectories included in the from$ specification, add the “FOF_FILESONLY” flag.

If, rather than moving all the files to the same destination folder, you want to move or rename them individually, initialise the fFlags member as follows:

        shfo.fFlags.l& = FOF_MULTIDESTFILES
        shfo.fFlags.h& = 0

Now the dest$ parameter must contain the same number of path/filename specifications as there are in from$, separated by NULs (CHR$0).