获取公共文件对话框中当前选择文件的真实名称?
人们可以在公共对话框的列表视图中获取所选项目的文本。但是无法获取其 PIDL,并且如果用户选择隐藏已知扩展名(默认),则在没有其扩展名或 PIDL 的情况下无法真正判断选择了哪个文件。
因此解决这个问题的可能方法可能是:
- 从 标准打开文件对话框。这 底层 IShellView 可以告诉什么 PIDL 用于当前 选择。所以如果我能简单地得到 持有 IShellView,我会 金的。不幸的是,我看不到 CDM_xxx 就可以了。而我 我无法思考 任何可能实现它的东西! :(
- 还有其他想法吗?!
我们过去依赖这样一个事实:Windows 9x、2000 和 XP 版本的通用文件对话框将每个项目的 PIDL 存储在 LVITEM 数据中(最初归功于 Paul DiLascia):
LPCITEMIDLIST pidlItem = (LPCITEMIDLIST )pListCtrl->GetItemData(nItem);
但是,从 Vista 的通用控件及以上版本开始,该技术失败了:(
有什么想法吗?
编辑:我不仅需要能够获取列表视图中当前选定项目的信息,但对于列表视图中的所有项目
EDIT2:我需要深入挖掘的原因:
在我们的应用程序的早期版本中,我们提供了以下功能:(1)按自定义按钮“预览”关闭对话框,但传输。向应用程序显示当前在视图中显示的项目列表(按可见顺序)以及当前突出显示的项目的索引。必须完整指定此列表 - 看到 3 个文件都是“J1329192”(当确实有 3 个文件时)。文件“J1329192.xyz”“J1329192.xzy”和“J1329192.zyx”[按顺序)没有用。
用户可以在“文件名:”字段中输入部分文件名过滤器,并且通用对话框将仅按照用户选择的排序顺序显示与给定部分过滤器匹配的文件。因此,要向应用程序准确报告用户想要预览的内容,我们需要能够从列表视图控件(或公共对话框本身)查询该信息。
我们还对文件对话框进行了其他增强 - 包括就地预览窗格,将用户当前的选择显示为缩略图,以及自定义最近位置界面等。所有这一切都是可能的(有很多Vista 之前的工作)。维斯塔之后,我遇到了重重困难。目前,我们使用标准文件对话框,其中只有很少的我们自己的功能,这不太适合客户(功能 X 发生了什么?!)
还有其他增强功能,但这只是一个很好的粗略概述。它们都归结为需要了解“真的,老实说,索引 X 的视图中具体有什么文件?”由于未知的原因 - 微软似乎并不觉得有必要提供这样的界面。事实上他们从来没有这样做过。只有通过一些黑客攻击和逆向工程,我们才能弄清楚事物的幕后工作原理并获得所需的信息。是的,这是不受支持的,是的,微软不可避免地破坏了我们的代码。我并不是真的为此责怪他们 - 我确实觉得令人讨厌的是他们更新、更漂亮的界面比旧界面更加封闭 - 而且他们没有提供更多的前期界面 - 支持的界面 - 来进行这些对话框增强。就像他们倒退了一大步,却没有前进(以进步的名义)。
One can get the text of the selected item in the list-view of a common dialog. But one can NOT get its PIDL, and if the user has chosen to hide known extensions (the default), then one cannot really tell what file was selected without either its extension or its PIDL.
So possible ways to solve this might be:
- Obtain an IShellView from the
standard open file dialog. The
underlying IShellView can tell what
the PIDL is for the current
selection. So if I could simply get
ahold of the IShellView, I'd be
golden. Unfortunately, I see no
CDM_xxx that would do it. And I
can't think off the top of my head
of anything that might achieve it!!!
:( - Some other idea?!
We used to rely upon the fact that the Windows 9x, 2000, and XP version of the common file dialog stored each item's PIDL in the LVITEM data (original credit to Paul DiLascia):
LPCITEMIDLIST pidlItem = (LPCITEMIDLIST)pListCtrl->GetItemData(nItem);
However, starting with Vista's common controls and above, that technique fails :(
Any thoughts?
EDIT: I need to be able to obtain this information not only for the currently selected item in the list view, but for all items in the list view.
EDIT2: The reason I need to dig so deep:
In prior versions of our app we provide the ability to: (1) Press a custom button "Preview" that closes the dialog, but transfers to the app the list of items currently displayed in the view, in their visible order, along with the index of the one currently highlighted. This list must be fully specified - seeing 3 files that are all "J1329192" (when there are really 3 files "J1329192.xyz" "J1329192.xzy" and "J1329192.zyx" [in that order) is not useful.
Users are allowed to type a partial filename filter into the "file name:" field, and the common dialog will show only files that match the given partial filter, in the sort-order that the user has chosen. So to report back to the app exactly what the user wanted to preview requires that we be able to query that information from the list view control (or the common dialog itself).
We do other enhancements to the file dialog as well - including an in-place preview pane that shows the user's current selection as a thumbnail, as well as have a custom recent-places interface, etc. All of this was possible (with a lot of work) prior to Vista. Post Vista, I have run into wall upon wall. For the time being, we use a standard file dialog with only a very few features of our own, which doesn't sit well with customers (what happened to feature X?!)
There are other enhancements, but that's a good rough overview. And they all boil down to requiring the knowledge of "really, honestly, what file specifically is in the view at index X?" And for unknown reasons - Microsoft doesn't seem to feel the need to provide such an interface. In fact they never did. Only through some hacking and reverse engineering were we able to figure out how things worked under the hood and get the needed info. And yes, that's unsupported, and yes, MS inevitably broke our code. I don't really blame them for that - what I do find obnoxious is that their newer, spiffier interface is far more closed than their older one - and they did not provide more up-front interfaces - supported interfaces - for doing these dialog enhancements. Its like they took a big couple of steps backwards - and none forwards (in the name of progress).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
发送 WM_USER+7 获取浏览器,然后获取其活动shell视图的IShellView接口。
您知道使用无证行为的通常后果吗?
Send WM_USER+7 to get the browser, and then get its active shell view's IShellView interface.
You know the usual consequence of using undocumented behavior right?
啊,我找到了。您需要使用
IFileOpenDialog
for Vista,它应该明确支持您提到的所有这些操作。Ah, I found it. You'll want to use
IFileOpenDialog
for Vista, which should explicilty support all those operations you mentioned.我知道这是一个旧线程,但在 Vista+ 中,旧式对话框仍然受支持。您可以关闭 Vista 风格并像以前一样保留所有自定义控件。这就是我们所做的:我们在挂钩到 CFileDialog 的模板中有一个自定义预览窗口,这似乎无法在 IFileDialog 中重现。
我相信您需要在构造函数中的 BOOL 参数中传递 FALSE 才能关闭 Vista 风格的对话框。
I know this is an old thread but, in Vista+, the old-style dialogs are still supported. You can turn off Vista-style and retain all your custom controls as before. That's what we do: we have a custom preview window in a template hooked into CFileDialog, which appears to be impossible to reproduce in IFileDialog.
I believe you need to pass FALSE in a BOOL parameter in the constructor to turn off the Vista-style dialogs.