简体   繁体   English

VB.net或Windows API:如何找出文件浏览器使用的图标?

[英]VB.net or Windows API: How to find out which icons the file explorer uses?

I am currently working on a Windows desktop application using VB.net where I would like to have a file and folder browsing interface directly integrated, ie the user does not have to open a file browser dialog to select files. 我目前正在使用VB.net在Windows桌面应用程序上工作,我想直接集成文件和文件夹浏览界面,即用户不必打开文件浏览器对话框即可选择文件。

My file browser should resemble the original Windows file explorer at least in that it uses the same icons for the most common locations. 我的文件浏览器至少应与原始Windows文件浏览器相似,因为它在最常见的位置使用相同的图标。 For example, I would like to include the "Favorites" folder with the appropriate icon (please note that this is NOT the IE favorites folder, but the folder which comes up when you type shell:links into the address bar of the file explorer). 例如,我想在“收藏夹”文件夹中包含适当的图标(请注意,这不是IE收藏夹文件夹,但是键入shell:links时出现的文件夹shell:links到文件浏览器的地址栏中) 。

My problem is fetching the icon. 我的问题是获取图标。 So far, I have written a wrapper class for some functions of the Windows API, notably SHGetKnownFolderPath and SHGetFileInfo . 到目前为止,我已经为Windows API的某些功能编写了包装器类,特别是SHGetKnownFolderPathSHGetFileInfo My approach is the following: 我的方法如下:

1) Use SHGetKnownFolderPath to get the full path to the respective location (which depends on the Windows version and localization). 1)使用SHGetKnownFolderPath获取到相应位置的完整路径(取决于Windows版本和本地化)。 This part works like expected. 这部分的工作与预期的一样。 For example, on my system (W7 Pro x64), SHGetKnownFolderPath returns "C:\\Users\\Administrator\\Links" when queried with the respective rfid. 例如,在我的系统(W7 Pro x64)上,当查询相应的rfid时, SHGetKnownFolderPath返回“ C:\\ Users \\ Administrator \\ Links”。

2) Use SHGetFileInfo to fetch the icon which Windows considers the default icon for the path obtained in 1). 2)使用SHGetFileInfo来获取Windows将其视为1)中获得的路径的默认图标的图标。 This part technically works as well, but the wrong icon is returned - wrong in the sense that it is another icon than Windows file explorer uses for the same location. 从技术上讲,该部分也可以正常工作, 但是返回的图标是错误的-从某种意义上来说,这是错误的,因为它是Windows File Explorer在同一位置使用的另一个图标。

I have tried that with four different locations (MyLibraries, MyFavorites (Links), MyComputer, MyNetwork). 我在四个不同的位置(MyLibraries,MyFavorites(链接),MyComputer,MyNetwork)进行了尝试。 The icon for MyLibraries was the expected one, the other three were completely different from the icons Windows file explorer uses. MyLibraries的图标是预期的图标,其他三个与Windows文件资源管理器使用的图标完全不同。

So I have got some questions : 所以我有一些问题

1) Is there any way to detect which icons are used by the standard Windows file explorer for certain folders, eg "Favorites" (C:\\Users\\Administrator\\Links on my machine)? 1)是否可以检测标准Windows文件浏览器对某些文件夹使用哪些图标,例如“收藏夹”(我机器上的C:\\ Users \\ Administrator \\ Links)? I would be interested in a general solution (ie a solution which works for all locations described here ). 我对通用解决方案(即适用于此处描述的所有位置的解决方案)感兴趣。

2) If there is no such way, I will find out the number (index) of all icons of interest in shell32.dll (actually, there are only a few at the moment). 2)如果没有这种方法,我将在shell32.dll中找出所有感兴趣的图标的编号(索引)(实际上,目前只有几个)。 Can I be sure that those indexes won't change in the future? 我可以确定这些索引将来不会更改吗?

3) According to this document , I have to call CoInitialize before using SHGetFileInfo . 3)根据本文档 ,在使用SHGetFileInfo之前,我必须调用CoInitialize I believe that the .NET framework automatically does this for the main thread before starting it and thus have not done it on my own yet (the development of the application has just started, and there is only one thread at the moment). 我相信.NET框架会在启动主线程之前自动对主线程执行此操作,因此我还没有自己做(应用程序的开发才刚刚开始,目前只有一个线程)。

I think that the missing call to CoInitialize can't be the cause for the "wrong" icons. 我认为缺少对CoInitialize调用不会成为“错误”图标的原因。 If I'm wrong here, please let me know. 如果我错了,请告诉我。

A potential solution could be using a .NET language or the native Windows API / SDK. 潜在的解决方案可能是使用.NET语言或本机Windows API / SDK。 As long as there is some way (even an extremely complicated one) to use the solution from within VB.net, I will be happy with it. 只要有某种方法(甚至是非常复杂的方法)在VB.net中使用该解决方案,我都会对此感到满意。

Explorer uses 2 ways to detect icon of any object, file or folder. 资源管理器使用两种方法来检测任何对象,文件或文件夹的图标。

1) call IShellFolder.GetUIObjectOf(IExtractIconA/W) and work with IExtractIcon. 1)调用IShellFolder.GetUIObjectOf(IExtractIconA / W)并使用IExtractIcon。

2) query IShellFolder.QueryInterface(IShellIcon) and call IShellIcon.GetIconOf. 2)查询IShellFolder.QueryInterface(IShellIcon)并调用IShellIcon.GetIconOf。

You can do the same. 你也可以做到的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM