最近、windows内で、ファイルをコピーするときに、SHFileOperationより、IFileOperationを利用したほうが良いと知りました。windows XP SP3以降はそうらしいです。
しかし、ネット上にIFileOperationの情報が少なくて、実装に大分時間がかかりました。。。それで、ネット上に備忘録も記載します。
参考になったサイトは以下で、そこを見れば、大体のことはわかると思います。
単体ファイルコピーのCopyItem関数についてはmsdnのサイト、そのままでいけました。その後、の複数ファイルをコピーするCopyItems関数の使い方を調べ出して、時間がかかりました。CopyItemをループで回してる人も多そうですね。もしかすると、そっちの方が、内部処理的に早いかもといまさら思いました 笑
CopyItemsを使う場合は以下のようにすれば、可能です。
int CFileManager::CopySelectedFileToSpecifiedFolder(list<CString>* listCopiedFilePath, CString csImportFolder){if (listCopiedFilePath == NULL || listCopiedFilePath->empty() == true) {return -1;}HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);if (!SUCCEEDED(hr)){return -1;}PIDLIST_ABSOLUTE abSourcePidl = NULL;SFGAOF attrs;int srcFileNum = listCopiedFilePath->size();PIDLIST_ABSOLUTE[] pPidlRawArray = new PIDLIST_ABSOLUTE[srcFileNum]);int no = 0;for (list<CString>::iterator it = listCopiedFilePath->begin(); it != listCopiedFilePath->end(); it++){CString strSource = *listCopiedFilePath->begin();hr = SHParseDisplayName(*it, NULL, &abSourcePidl, 0, &attrs);if (FAILED(hr)){return -1;}pPidlRawArray[no] = abSourcePidl;no++;}delete[] PIDLIST_ABSOLUTE;CComPtr<IShellItemArray> pShellItemArr = NULL;hr = SHCreateShellItemArrayFromIDLists(srcFileNum, (LPCITEMIDLIST*)pPidlRawArray.get(), &pShellItemArr);if (FAILED(hr)){return -1;}PIDLIST_ABSOLUTE abDestPidl = NULL;hr = SHParseDisplayName(csImportFolder, NULL, &abDestPidl, 0, &attrs);if (FAILED(hr)){return -1;}CComPtr<IShellItem2> pDestShellItem;hr = SHCreateItemFromIDList(abDestPidl, IID_IShellItem2, reinterpret_cast<LPVOID*>(&pDestShellItem));if (FAILED(hr)){return -1;}CComPtr<IFileOperation> fileOp;hr = fileOp.CoCreateInstance(CLSID_FileOperation);if (FAILED(hr)){return -1;}hr = fileOp->CopyItems(pShellItemArr, pDestShellItem);if (FAILED(hr)){return -1;}hr = fileOp->PerformOperations();if (FAILED(hr)){return -1;}CoUninitialize();return 0;}
std::listを使ってたり、一部コード修正したので、コンパイルは未確認だったりしますが、ほぼ同じコードで動作確認しています。
ご参考までにご利用ください。
ではでは~