Introduction
This article is a very simple article, illustrating the basic use of SHFileOperation
and how it can be used to provide a multi copying.
Using the code
The code is quite simple, it is an initial explanation of SHFileOperation
to illustrate how to copy multi files and multi folders from multi sources to multi destinations. Before starting to explain the code, let me show you the prototype of SHFileOperation
along with the structure that is passed to it:
int WINAPI SHFileOperation(LPSHFILEOPSTRUCT lpFileOp);
LPSHFILEOPSTRUCT
is as you assumed a pointer to SHFILEOPSTRUCT
which is defined as follows:
typedef struct _SHFILEOPSTRUCT
{
HWND hwnd;
UINT wFunc;
LPCSTR pFrom;
LPCSTR pTo;
FILEOP_FLAGS fFlags;
BOOL fAnyOperationsAborted;
LPVOID hNameMappings;
LPCSTR lpszProgressTitle;
} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;
I won't go into the details of this structure, it can be easily found in the MSDN. The two elements that really concern us in this structure are the pFrom
and pTo
, which point to the strings containing the source files/folders and destination files/folders respectively. Honestly, I would like to consider them as lists of strings because they can carry several source files/folders separated by '\0' (null) and the last element should be followed by '\0\0' (double null).
To keep this as simple as possible, all the code revolves around filling two string lists.
LPCSTR pFrom;
LPCSTR pTo;
pFrom
is a string pointer of the source paths separated by '\0' and terminated by '\0\0'.
pTo
is a string pointer of the destination paths separated by '\0' and terminated by '\0\0'.
So, basically what we have to do is fill these two lists and pass the structure to SHFileOperation
and the function handles all the details. Of course, we have to set the appropriate flags to get it working as we like. A typical flag setting would be as follows:
FOF_MULTIDESTFILES|FOF_NOCONFIRMMKDIR|FOF_NOCONFIRMATION
The code has been kept as simple as possible. (All the code has been added in the interface- yeah I know bad design :-P.) To keep this as simple as possible and not to get lost in side details, the code has been commented well, however most of the code written is just interface adjusting code. The main action occurs in the following function:
void CMultiCopyDlg::OnBnClickedBtnCopy()
{
szDisFileLst+='\0';
szFileLst+='\0';
szDisDireLst+='\0';
szDirLst+='\0';
SHFILEOPSTRUCT SHFileOp,SHDirOp;
if(bFileInList)
{
ZeroMemory(&SHFileOp, sizeof(SHFILEOPSTRUCT));
SHFileOp.hwnd = NULL;
SHFileOp.wFunc = FO_COPY;
SHFileOp.pFrom = szFileLst;
SHFileOp.pTo = szDisFileLst;
SHFileOp.fFlags = FOF_MULTIDESTFILES;
SHFileOperation(&SHFileOp);
}
if(bDirInList)
{
ZeroMemory(&SHDirOp, sizeof(SHFILEOPSTRUCT));
SHDirOp.hwnd = NULL;
SHDirOp.wFunc = FO_COPY;
SHDirOp.pFrom = szDirLst;
SHDirOp.pTo = szDisDireLst;
SHDirOp.fFlags =
FOF_MULTIDESTFILES|FOF_NOCONFIRMMKDIR|FOF_NOCONFIRMATION;
SHFileOperation(&SHDirOp);
}
}
After the structures have been filled out all we do is fill the structure SHFILEOPSTRUCT
and send it to the function for execution.
Where to go from here
Well there is a lot that hasn't been explored by this function plus there is some sort of bug that hasn't been handled while copying folders. The function only copies the files in the source folder to the destination folder and not the whole folder into the destination folder.
Thanks
To Dino Esposito for his wonderful book Visual C++ Windows Shell programming and Ahmad Ismail's article about multi copying (basically the same but I wanted to focus on the main details :-P).