【发布时间】:2017-11-02 23:47:40
【问题描述】:
--------------更新第五次-------------------- ------------
if (fIsFolder)
{
dwAttribs |= SFGAO_FOLDER;
}
else
{
dwAttribs |= SFGAO_SYSTEM;
dwAttribs |= SFGAO_FILESYSTEM;
}
if (nLevel < g_nMaxLevel)
{
dwAttribs |= SFGAO_HASSUBFOLDER;
dwAttribs |= SFGAO_FILESYSANCESTOR;
}
现在这个在应用程序 A、stackoverflow 图片上传文件对话框和常规文件夹资源管理器中正常工作。
----------------------------------- -------更新第四次-------------------------------------------- -----------------
添加 dwAttribs |= SFGAO_SYSTEM; 之后,现在至少对于应用程序 A,它在文件对话框中按预期工作。但该文件夹在常规文件夹对话框或CWFileDialog 中仍然不可点击。
if (fIsFolder)
{
dwAttribs |= SFGAO_FOLDER;
dwAttribs |= SFGAO_FILESYSTEM;
dwAttribs |= SFGAO_FILESYSANCESTOR;
}
else
{
dwAttribs |= SFGAO_SYSTEM;// this line of code works better
dwAttribs |= SFGAO_FILESYSTEM;
}
------------------------更新第三次---------- ------------------------------------------- 这是虚拟文件夹的ISHellFolder中的代码:
编辑以下代码添加dwAttribs |= SFGAO_FILESYSTEM;后,在文件夹视图中双击该文件夹时无法浏览该文件夹。但是可以在树形视图中左键打开它。
HRESULT CFolderViewImplFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, ULONG *rgfInOut)
{
// If SFGAO_FILESYSTEM is returned, GetDisplayNameOf(SHGDN_FORPARSING) on that item MUST
// return a filesystem path.
HRESULT hr = E_INVALIDARG;
DWORD dwAttribs = 0;
dwAttribs |= SFGAO_FILESYSTEM;
if (1 == cidl)
{
int nLevel = 0;
hr = _GetLevel(apidl[0], &nLevel);
if (SUCCEEDED(hr))
{
BOOL fIsFolder = FALSE;
hr = _GetFolderness(apidl[0], &fIsFolder);
if (SUCCEEDED(hr))
{
if (fIsFolder)
{
dwAttribs |= SFGAO_FOLDER;
}
if (nLevel < g_nMaxLevel)
{
dwAttribs |= SFGAO_HASSUBFOLDER;
}
}
}
}
*rgfInOut &= dwAttribs;
return hr;
}`
或者
DWORD dwAttribs = 0;
if (1 == cidl)
{
int nLevel = 0;
hr = _GetLevel(apidl[0], &nLevel);
if (SUCCEEDED(hr))
{
BOOL fIsFolder = FALSE;
hr = _GetFolderness(apidl[0], &fIsFolder);
if (SUCCEEDED(hr))
{
if (fIsFolder)
{
dwAttribs |= SFGAO_FOLDER;
dwAttribs |= SFGAO_FILESYSTEM;
dwAttribs |= SFGAO_FILESYSANCESTOR;
}
else
{
dwAttribs |= SFGAO_SYSTEM;
}
if (nLevel < g_nMaxLevel)
{
dwAttribs |= SFGAO_HASSUBFOLDER;
}
}
}
}
*rgfInOut &= dwAttribs;
其他代码同update 2nd。
奇怪的是,在我编辑这些代码之后,通常使用CFileDialog 的应用程序A(不包装它,未将m_bPickNonFileSysFoldersMode 设置为true)可以按我的预期正常显示所有虚拟文件夹。
但在所有其他应用程序中(包括使用CWFileDilao 将m_bPickNonFileSysFoldersMode 设置为true 的应用程序仍然无法查看虚拟文件夹。
---------------------------------------更新第二次------ -------------------
我编写了一个派生自 CFileDialog 的简单类:
class CWFileDlg : public CFileDialog
{
public:
CWFileDlg(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = TRUE);
~CWFileDlg();
};
CWFileDlg::CWFileDlg(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt,
LPCTSTR lpszFileName,
DWORD dwFlags,
LPCTSTR lpszFilter,
CWnd* pParentWnd,
DWORD dwSize,
BOOL bVistaStyle) : CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, dwSize, bVistaStyle)
{
m_bPickNonFileSysFoldersMode = TRUE;
}
CWFileDlg::~CWFileDlg()
{
}
那我这样称呼它:
CWFileDlg dlg(TRUE, NULL, 0, OFN_SHAREAWARE | OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, L"all(*.*)|*.*||", this);
BOOL IsPickNonFileSysFoldersMode = dlg.IsPickNonFileSysFoldersMode();
//the value it gets is 1, which is TRUE
INT_PTR result = dlg.DoModal();
但在弹出的对话框中,虚拟文件夹仍然不可见。它的树视图也是不可见的。 - - - - - - - - - - - - - - - - - - - - - 更新 - - - - ---------------------
protected:
BOOL m_bVistaStyle;
BOOL m_bPickFoldersMode;
BOOL m_bPickNonFileSysFoldersMode;
DWORD m_dwCookie;
void* m_pIFileDialog;
void* m_pIFileDialogCustomize;
m_bPickNonFileSysFoldersMode 不是公共类型。我怎样才能将其设置为 TRUE ?
Error 1 error C2248: 'CFileDialog::m_bPickNonFileSysFoldersMode' : cannot access protected member declared in class 'CFileDialog' c:\users\liyuan.liu\documents\dp-dll\testvirtualfolder\browser2\browser2\browser2dlg.cpp 166 1 browser2
通过使用 Microsoft windows 示例代码,我使用 shell 命名空间扩展在 windows 7 上安装了一个虚拟文件夹。 以下屏幕截图是使用常规文件夹浏览器打开它:
然后我写了一个可以创建文件对话框的项目:
CFileDialog dlg(TRUE, NULL, 0, OFN_SHAREAWARE | OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, L"all(*.*)|*.*||", this);
INT_PTR result = dlg.DoModal();
但是,在文件浏览器中,虚拟文件夹是不可见的:
但是!当我尝试将屏幕截图上传到 StackOverflow(我使用的网络浏览器是 chrome)时,用于选择文件的文件对话框可以显示虚拟文件夹的树视图(仅树视图):
通过谷歌搜索,似乎 CFileDialog 不支持显示虚拟文件夹,因为它实际上并不存在于系统中。有什么解决方案可以解决这个问题吗? 我也试过
bi.pidlRoot = pidlVirtual;
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | BIF_BROWSEINCLUDEFILES | BIF_BROWSEFILEJUNCTIONS;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
也不行。
【问题讨论】:
-
您是否创建并注册了 32 位和 64 位 NSE?
-
CFileDialog在 Visual Studio 2008 及更高版本中默认包装IFileDialog。IFileDialog绝对支持虚拟文件夹和 SNE(这是它对旧的Get(Open|Save)FileName()API 的重大改进)。您使用的是什么版本的 Visual Studio?也许您的版本中的CFileDialog正在使用较旧的仅文件系统 API。你试过直接使用IFileDialog吗?
标签: c++ windows registry shell-extensions shell-namespace-extension