HowTo: Display progress dialog using IFileOperation

会有一股神秘感。 提交于 2020-01-03 01:51:11

问题


I’m trying to get a progress dialog to display for my copy operation in some sample code. I’m using IFileOperation because I found that using SHFileOperation will not display a progress dialog if the files have already been copied to the target location. My hope is that IFileOperation is a little more sophisticated and can handle that situation. Here’s the sample code I’ve tried….

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();

The sample is trying to copy all files and folders from one location (oldDirectory) to another (newDirectory). The copy operation does copy everything correctly. I’m looking for help in getting the progress dialog to display during the operation. According to IFileOperation, I should be able to set the progress dialog through IOperationsProgressDialog. The documentation for this is extremely thin. I have not been able to find any samples showing how to fit the two together. Does anyone have experience with these two interfaces?


回答1:


If you just need progress dialog, then remove the reference to IOperationsProgressDialog

CopyItem only prepares the items for copying, therefore IOperationsProgressDialog::Update... will not update any UI. Actual copying begins when PerformOperations is called.

UI dialog won't show if there are only a few files, because it's done too quickly. Maybe you want to remove FOF_RENAMEONCOLLISION to make it easier for testing. This should be exact same thing as 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...");


来源:https://stackoverflow.com/questions/33024157/howto-display-progress-dialog-using-ifileoperation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!