什么是“Shell 命名空间”?新建文件夹的方法?
显然,这对于 win32 api - CreateDirectory() 来说是微不足道的。但我正在尝试托管一个 IShellView,并且希望以最面向 shell 的方式来做到这一点。我本以为 IShellFolder 中会有一个 createobject 或 createfolder 或类似的东西。但 IShellView 和 IShellFolder 甚至 IFolderView 似乎都没有类似的东西。
有没有一种 shell 编程方式来创建新文件夹?或者我是否需要使用路径名(老式的方式)创建一个文件夹?
如果我必须通过 CreateDirectory() 来完成此操作,那么我的下一个问题可能是:关于如何让 IShellView / IFolderView 实际看到这个新对象并将其显示给用户的任何想法?
动机:创建我自己的文件对话框替代品,我想提供标准 XP 样式文件对话框的“新文件夹”工具栏图标功能。
编辑:我继续使用 CreateDirectory 创建了一些基本上可以工作的东西。但是,我仍然希望有更好的方法来做到这一点,但这样您就可以看到它是如何工作的,并提供更好的想法来更好地解决这个问题:
PidlUtils::Pidl pidl(m_folder);
CFilename folderName(GetDisplayNameOf(pidl), "New Folder");
for (int i = 2; folderName.Exists(); ++i)
folderName.SetFullName(FString("New Folder (%d)", i));
if (!CPathname::Create(folderName, false))
throw CContextException("Unable to create a new folder here: ");
// get the PIDL for the newly created folder
PidlUtils::Pidl pidlNew;
#ifdef UNICODE
const wchar_t * wszName = folderName.c_str();
#else
wchar_t wszName[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, folderName.GetFullName(), -1, wszName, MAX_PATH);
#endif
m_hresult = m_folder->ParseDisplayName(NULL, NULL, wszName, NULL, pidlNew, NULL);
if (FAILED(m_hresult))
throw CLabeledException(FString("Unable to get the PIDL for the new folder: 0x%X", m_hresult));
// upgrade our interface so we can select & rename it
CComQIPtr<IShellView2> sv2(m_shell_view);
if (!sv2)
throw CLabeledException("Unable to obtain the IShellView2 we need to rename the newly created folder.");
// force it to see thew new folder
sv2->Refresh();
// select the new folder, and begin the rename process
m_hresult = sv2->SelectAndPositionItem(pidlNew, SVSI_EDIT|SVSI_DESELECTOTHERS|SVSI_ENSUREVISIBLE|SVSI_POSITIONITEM, NULL);
if (FAILED(m_hresult))
throw CLabeledException(FString("Unable to select and position the new folder item: 0x%X", m_hresult));
Obviously this is trivial to do with win32 api - CreateDirectory(). But I'm trying to host an IShellView, and would like to do this the most shell-oriented way. I would have thought that there would be a createobject or createfolder or some such from an IShellFolder. But neither IShellView nor IShellFolder nor even IFolderView seem to have anything quite like this.
Is there a Shell-programming way to create a new folder? Or do I need to create a folder using a pathname, the old-fashioned way?
If I have to do it via CreateDirectory(), then my next question might be: any ideas as to how to get the IShellView / IFolderView to actually see this new object and display it to the user?
Motivation: Creating my own File Dialog replacement and I want to provide the "new folder" toolbar icon functionality of the standard XP-style file dialog.
EDIT: I went ahead and created something that basically works, using CreateDirectory. However, I'm still hoping that there's a better way to do this, but so that you can see how that works, and to offer better ideas as to solve this issue better:
PidlUtils::Pidl pidl(m_folder);
CFilename folderName(GetDisplayNameOf(pidl), "New Folder");
for (int i = 2; folderName.Exists(); ++i)
folderName.SetFullName(FString("New Folder (%d)", i));
if (!CPathname::Create(folderName, false))
throw CContextException("Unable to create a new folder here: ");
// get the PIDL for the newly created folder
PidlUtils::Pidl pidlNew;
#ifdef UNICODE
const wchar_t * wszName = folderName.c_str();
#else
wchar_t wszName[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, folderName.GetFullName(), -1, wszName, MAX_PATH);
#endif
m_hresult = m_folder->ParseDisplayName(NULL, NULL, wszName, NULL, pidlNew, NULL);
if (FAILED(m_hresult))
throw CLabeledException(FString("Unable to get the PIDL for the new folder: 0x%X", m_hresult));
// upgrade our interface so we can select & rename it
CComQIPtr<IShellView2> sv2(m_shell_view);
if (!sv2)
throw CLabeledException("Unable to obtain the IShellView2 we need to rename the newly created folder.");
// force it to see thew new folder
sv2->Refresh();
// select the new folder, and begin the rename process
m_hresult = sv2->SelectAndPositionItem(pidlNew, SVSI_EDIT|SVSI_DESELECTOTHERS|SVSI_ENSUREVISIBLE|SVSI_POSITIONITEM, NULL);
if (FAILED(m_hresult))
throw CLabeledException(FString("Unable to select and position the new folder item: 0x%X", m_hresult));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,您可以 获取 IContextMenu 并查找子菜单,但是为什么要麻烦呢,只需调用 SHChangeNotify 调用 CreateDirectory 后
Yes, you can get IContextMenu and look for sub menus, but why bother, just call SHChangeNotify after you call CreateDirectory
Shell 文件夹通常实现 IStorage 接口,因此这非常简单。例如,以下命令在桌面上创建一个名为“abcd”的文件夹:
Shell folders usually implement the IStorage interface, so this is pretty simple. For example, the following creates a folder named "abcd" on the desktop:
Win32 API函数CreateDirectory似乎是“正确的方法”。至少,我找不到更好的方法 - 而且这里的答案并没有真正阐明更好的方法。
The Win32 API function CreateDirectory seems to be the "correct way". At least, I can find nothing better - and the answers here don't really shed any light on a better way to do it.