我试图限制用户访问某个位置(Windows,Program Files等)并通过实现IFolderFilter接口来实现这一点。
一切似乎都很好,直到ShouldShow函数被调用,然后它们似乎都崩溃了。我们传入的初始文件夹是C:\ ProgramData \ Company \ App \ Year,我们看到了,但文件对话框显示它挂在桌面上,这就是为什么当我检查pidl中包含的文件夹时,就像C: \ Users \ Graham.Reeds \ Desktop \ Windows,C:\ Users \ Graham.Reeds \ Desktop \ Program Files等。这似乎阻止了它们与我希望阻止用户选择的CSIDL_变量相匹配。 / p>
我尝试使用SHGetPathFromIDListEx
和SHGetKnownFolderIDList
,但VS2010给了我'标识符X未定义'但我包含了shlobj并链接到Shell32.lib。
HRESULT STDMETHODCALLTYPE ShouldShow(IShellFolder* sf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST pidlItem)
{
HRESULT resultCode = S_OK;
ULONG attributes = 0UL;
if (SUCCEEDED(sf->GetAttributesOf(1, &pidlItem, &attributes)))
{
char szPath[_MAX_PATH];
BOOL f = SHGetPathFromIDList(pidlItem, szPath);
// BOOL f = SHGetPathFromIDListEx(pidlItem, szPath, _MAX_PATH, 0);
// FOLDERID_Windows / CSIDL_WINDOWS
PIDLIST_ABSOLUTE pidl;
// if (SUCCEEDED(SHGetKnownFolderIDList(FOLDERID_Windows, 0, 0, &pidl)))
if (SUCCEEDED(SHGetFolderLocation(0, CSIDL_WINDOWS, 0, 0, &pidl)))
{
HRESULT hres = sf->CompareIDs(0, pidlItem, pidl);
if ((short)HRESULT_CODE(hres) == 0)
{
resultCode = S_FALSE;
}
ILFree(pidl);
}
}
return resultCode;
}
我需要做的是能够阻止某些文件夹出现在浏览文件夹中。我怎么能这样做?
答案 0 :(得分:0)
SHGetPathFromIDList
需要一个绝对PIDL(一个从名称空间层次结构顶部的桌面开始向下工作),但是你传递的是pidlItem
,它是一个单独的子PIDL({{1} }}相对于pidlItem
,而不是桌面。
您可以使用带有pidlFolder
标记的SHGetPathFromIDList
代替使用IShellFolder::GetDisplayNameOf
来获取商品的完整路径(例如SHGDN_FORPARSING
)。
您的sf->GetDisplayNameOf(pidlItem, ...)
电话也会出现同样的问题。 CompareIDs
需要两个相对于指定文件夹的PIDL,但是您尝试使用一个相对PIDL和一个绝对值来调用它。
一种解决方案是使用IShellFolder::CompareIDs
从pidlFolder
和pidlItem
创建绝对PIDL并将其传递给ILCombine
,但您需要使用桌面文件夹进行比较(从CompareIDs
获得)而不是使用SHGetDesktopFolder
。
答案 1 :(得分:0)
您正在将苹果(文件夹相对PIDL)与橙子(绝对PIDL)进行比较。您需要将相对PIDL转换为绝对PIDL,然后才能将其与位于Shell命名空间的不同文件夹中的另一个项目进行比较。
尝试更像这样的事情:
bool ArePIDLsTheSameItem(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
{
if (ILIsEqual(pidl1, pidl2))
return true;
IShellFolder *sfDesktop = NULL;
if (SHGetDesktopFolder(&sfDesktop) == S_OK)
{
HRESULT hres = sfDesktop->CompareIDs(0, pidl1, pidl2);
sfDesktop->Release();
if (HRESULT_CODE(hres) == 0)
return true;
}
return false;
}
HRESULT STDMETHODCALLTYPE ShouldShow(IShellFolder* sf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST pidlItem)
{
HRESULT resultCode = S_OK;
PIDLIST_ABSOLUTE pidlWindows = NULL;
//if (SUCCEEDED(SHGetKnownFolderIDList(FOLDERID_Windows, 0, 0, &pidlWindows)))
if (SUCCEEDED(SHGetFolderLocation(0, CSIDL_WINDOWS, 0, 0, &pidlWindows)))
{
if (ArePIDLsTheSameItem(pidlWindows, pidlFolder))
{
// ignore anything inside the Windows folder itself...
resultCode = S_FALSE;
}
else if (ILIsParent(pidlWindows, pidlFolder, FALSE))
{
// ignore anything inside a subfolder of the Windows folder...
resultCode = S_FALSE;
}
else
{
PIDLIST_ABSOLUTE pidlFolderAndItem = ILCombine(pidlFolder, pidlItem);
if (pidlFolderAndItem)
{
if (ArePIDLsTheSameItem(pidlFolderAndItem, pidlWindows))
{
// ignore the Windows folder itself...
resultCode = S_FALSE;
}
ILFree(pidlFolderAndItem);
}
}
ILFree(pidlWindows);
}
return resultCode;
}