c++ - 在 C++ 中使用 IFileDialog 以编程方式预选择

标签 c++ windows winapi

我很困惑 IFileDialog 是否能够以编程方式选择对话框内的项目,即使用户没有选择。

例如。 IFileDialog shows with nothing selected by default

我希望能够打开 IFileDialog,然后在对话框中选择默认项目/文件夹。 前任。 Default selects an item/folder inside the dialog

顺便说一下,上图中。我手动单击/选择文件夹。 但我希望在 IFileDialog 中实现默认选定的项目。

最佳答案

zett42 建议的程序有效。您需要实现您自己的 IFileDialogEvents 版本。使用 IFileDialog::Advise Hook 后,您可以查询 IShellView 的方式,这样您就可以更改选择。

这个例子有点愚蠢,因为我也强制目录确保我有一个可以选择的文件。

struct MyIFileDialogEvents : public IFileDialogEvents {
    bool forcedDir, forcedSel;
    MyIFileDialogEvents() : forcedDir(false), forcedSel(false) {}
    ...
};

STDMETHODIMP MyIFileDialogEvents::OnFolderChanging( IFileDialog *pfd, IShellItem*psiFolder)
{
    if (forcedDir) return S_OK; else forcedDir = true;
    IShellItem*psiwindir;
    HRESULT hr = SHGetKnownFolderItem(FOLDERID_Windows, KF_FLAG_DEFAULT, NULL, IID_IShellItem, (void**) &psiwindir);
    if (!hr)
    {
        hr = pfd->SetFolder(psiwindir); // MSDN says it is OK to change the folder in OnFolderChanging with SetFolder
        psiwindir->Release();
    }
    if (FAILED(hr)) forcedSel = true;
    return S_OK;
}

STDMETHODIMP MyIFileDialogEvents::OnFolderChange(IFileDialog *pfd)
{
    if (forcedSel || !forcedDir) return S_OK; else forcedSel = true;
    IShellItem*psiwindir, *psiexp;
    HRESULT hr = SHGetKnownFolderItem(FOLDERID_Windows, KF_FLAG_DEFAULT, NULL, IID_IShellItem, (void**) &psiwindir);
    if (!hr)
    {
        hr = SHCreateItemFromRelativeName(psiwindir, L"Explorer.exe", NULL, IID_IShellItem, (void**) &psiexp);
        psiwindir->Release();
        if (!hr)
        {
            IServiceProvider*pSP;
            IShellBrowser*pSB;
            IShellView*pSV;
            if (!pfd->QueryInterface(IID_IServiceProvider, (void**) &pSP))
            {
                if (!pSP->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&pSB))
                {
                    if (!pSB->QueryActiveShellView(&pSV))
                    {
                        PIDLIST_ABSOLUTE pidl;
                        if (!SHGetIDListFromObject(psiexp, &pidl))
                        {
                            pSV->SelectItem(ILFindLastID(pidl), SVSI_SELECT|SVSI_ENSUREVISIBLE|SVSI_FOCUSED|SVSI_DESELECTOTHERS);
                            CoTaskMemFree(pidl);
                        }
                        pSV->Release();
                    }
                    pSB->Release();
                }
                pSP->Release();
            }
            psiexp->Release();
        }
    }
    return S_OK;
}

关于c++ - 在 C++ 中使用 IFileDialog 以编程方式预选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50232092/

相关文章:

angularjs - 我已经安装了 angular cli 但它在 cmd 中无法识别

windows - 更改多表单应用程序中的窗口顺序

python - 将 Qt 嵌入 native 窗口 (Windows)

c++ - 多级接口(interface) - 返回指向基接口(interface)的指针

c++ - 使用第三方库 (sbpl)

c++ - 为什么我的 C++ 代码在使用 read(...) 函数后会导致段错误?

python - 不确定如何修复此 Cmd 命令错误?

windows - 使用批处理文件检查特定文件大小

python - 如何从事件窗口中检索选定的文本

c++ - 提升灵气属性传播