在新目录上设置可见列

时间:2019-06-27 23:44:55

标签: c++ winapi directory com multiple-columns

我正在开发一个外壳扩展,用于创建一个新文件夹。我希望新文件夹在用户浏览后在详细信息视图中显示一组自定义列。我认为也许IColumnManager是完成此操作的正确接口。这是在创建新文件夹(我已经缩写为PKEY)之后要尝试的代码:

IShellFolder* psdf;
if (SUCCEEDED(SHGetDesktopFolder(&psdf))) {

    PIDLIST_ABSOLUTE pidl = ILCreateFromPath(pwszNewFolderPath);

    LPSHELLFOLDER psf;
    if (SUCCEEDED(psdf->BindToObject(pidl, NULL, IID_IShellFolder, (void**)& psf))) {

        SFV_CREATE sfvc = { 0 };
        sfvc.cbSize = sizeof(SFV_CREATE);
        sfvc.pshf = psf;
        sfvc.psvOuter = NULL;
        sfvc.psfvcb = NULL;

        LPSHELLVIEW psv;
        if (SUCCEEDED(SHCreateShellFolderView(&sfvc, &psv))) {

            IColumnManager* pcm;
            if (SUCCEEDED(psv->QueryInterface(IID_IColumnManager, (void**)& pcm))) {

                PROPERTYKEY rgkeys[] = {
                    PKEY_ [...] ,
                    PKEY_ [...] ,
                    PKEY_ [...] ,
                };

                if (SUCCEEDED(pcm->SetColumns(rgkeys, ARRAYSIZE(rgkeys)))) {
                    //MessageBoxA(NULL, "Success?", "Success?", MB_OK);
                }
                pcm->Release();
            }
            psv->Release();
        }
        psf->Release();
    }
    psdf->Release();
}

此代码成功执行了每个方法调用,但是当我进入新创建的文件夹时,列不是所期望的。难道我做错了什么? IColumnManager仅在给定文件夹已经可见时才起作用吗?也许仅适用于IExplorerBrowser之类的东西?如果界面不正确,当用户浏览文件夹时,如何设置一组自定义列?谢谢。

编辑:该代码实际上在文件夹的活动视图上有效。但是,它对列所做的更改不会持久化(与用户手动进行的列更改一样,持久化确实如此)。所以我想我想知道是否有办法使它们持久化,或者是否还有另一种方法来设置列而不需要活动视图。再次感谢。

此外,SHGetViewStatePropertyBag是否有意义?和IExplorerBrowser::SetPropertyBag一起?还是不能将它们用于常规的Shell文件夹?

1 个答案:

答案 0 :(得分:0)

SHCreateShellFolderView创建一个IShellView提供的shell的实例,此接口知道如何保存其设置,但是会向其IShellBrowser主机请求存储实现。 IShellView::CreateViewWindow将视图连接到其主机。

IShellView::SaveViewState

  

保存命令行管理程序的视图设置,以便可以在后续的浏览会话中恢复当前状态。

但是您需要实现IShellBrowser并调用SHGetViewStatePropertyBag之类的东西来获取Explorer所使用的存储实现,并在需要时将其提供给IShellView。这里的大多数详细信息都没有记录,我建议您使用IExplorerBrowser导航到该文件夹​​,而不是尝试自己托管IShellView。使用“外壳”作为包装袋名称。

SHGetViewStatePropertyBag已在Windows XP中添加,但那里不存在IExplorerBrowser。如果需要支持the undocumented interface,这是IShellViewSHGetViewStatePropertyBag之间的粘合剂。

在Windows 2000和更早的版本上,我认为状态直接存储在IStream中,而不是存储在属性包中。 OpenRegStream用于打开流,但是计算MRU路径的函数没有记录,但是KB 812003至少告诉您根目录。