HowTo:使用IFileOperation显示进度对话框

时间:2015-10-08 19:15:19

标签: c++ interface com mfc windows-shell

我正在尝试获取一个进度对话框,以便在一些示例代码中显示我的复制操作。我正在使用IFileOperation因为我发现如果文件已经复制到目标位置,使用 SHFileOperation 显示进度对话框。我希望IFileOperation更复杂一点,可以处理这种情况。 这是我试过的示例代码......

CComPtr<IOperationsProgressDialog> opProgressDlg;
HRESULT hr = opProgressDlg.CoCreateInstance(CLSID_ProgressDialog);

CComPtr<IFileOperation> fileOp;
hr = fileOp.CoCreateInstance(CLSID_FileOperation);
hr = fileOp->SetOperationFlags(FOF_RENAMEONCOLLISION | FOFX_PRESERVEFILEEXTENSIONS | FOFX_NOMINIMIZEBOX);
hr = fileOp->SetProgressDialog(opProgressDlg);

hr = opProgressDlg->StartProgressDialog(m_hWnd, OPPROGDLG_DEFAULT);
hr = opProgressDlg->SetMode(PDM_DEFAULT);
hr = opProgressDlg->SetOperation(SPACTION_COPYING);
oldDirectory += _T("*.*");

CFileFind finder;
BOOL bWorking = finder.FindFile(oldDirectory);
while (bWorking)
    {
    bWorking = finder.FindNextFile();
    if (finder.IsDots())
        continue;
    CString name = finder.GetFilePath();
    IShellItem *psiFrom = nullptr;
    hr = SHCreateItemFromParsingName(CT2CW(name), NULL, IID_PPV_ARGS(&psiFrom));
    IShellItem *psiTo = NULL;
    hr = SHCreateItemFromParsingName(CT2CW(newDirectory), NULL, IID_PPV_ARGS(&psiTo));
    hr = fileOp->CopyItem(psiFrom, psiTo, CT2CW(finder.GetFileName()), NULL);
    //hr = opProgressDlg->UpdateLocations(psiFrom, psiTo, psiTo);
    }

opProgressDlg->StopProgressDialog();

hr = fileOp->PerformOperations();

示例正在尝试将所有文件和文件夹从一个位置(oldDirectory)复制到另一个位置(newDirectory)。 复制操作会正确复制所有内容。我正在寻找帮助,以便在操作期间显示进度对话框。根据IFileOperation,我应该可以通过IOperationsProgressDialog设置进​​度对话框。这方面的文档非常薄。我找不到任何样品来展示如何将两者结合在一起。有没有人有这两种接口的经验?

1 个答案:

答案 0 :(得分:0)

如果您只需要进度对话框,请删除对IOperationsProgressDialog

的引用

CopyItem仅准备要复制的项目,因此IOperationsProgressDialog::Update...不会更新任何UI。在调用PerformOperations时开始实际复制。

UI对话框不会显示是否只有少量文件,因为它的执行速度太快。也许您想删除FOF_RENAMEONCOLLISION以便于测试。这应该与SHFileOperation完全相同。

CString srcDir = L"c:\\test\\src";
CString dstDir = L"c:\\test\\dst";

CComPtr<IFileOperation> fileOp;
fileOp.CoCreateInstance(CLSID_FileOperation);
fileOp->SetOperationFlags(FOFX_SHOWELEVATIONPROMPT);

srcDir += L"\\*";
CFileFind finder;
BOOL next = finder.FindFile(srcDir);
while (next)
{
    next = finder.FindNextFile();
    if (finder.IsDots())
        continue;

    CComPtr<IShellItem> src, dst;
    if (S_OK != SHCreateItemFromParsingName(finder.GetFilePath(), NULL, IID_PPV_ARGS(&src)))
        continue;

    if (S_OK != SHCreateItemFromParsingName(dstDir, NULL, IID_PPV_ARGS(&dst)))
        continue;

    fileOp->CopyItem(src, dst, 0, NULL);
}

MessageBox(L"nothing copied so far...");
hr = fileOp->PerformOperations();
MessageBox(L"done...");