为 C# 中的自定义图标创建窗口扩展处理程序

本文关键字:窗口 扩展 处理 程序 创建 图标 自定义 | 更新日期: 2023-09-27 18:36:00

我想通过dll处理文件扩展名图标,并根据Windows资源管理器中的文件内容提供图标(类似于PSD文件的缩略图图标。Photoshop 处理扩展名.psd并为每个文件生成缩略图)

我在 C# 中制作了一个 dll,它可以很好地处理LoadGetIconLocation函数。似乎 Windows 应该在 GetIconLocation 之后调用 Extract 函数,但它不会!

接口:

   [ComVisible(true), ComImport, Guid("000214eb-0000-0000-c000-000000000046"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
   public interface IExtractIcon
   {
        [PreserveSig]
        uint GetIconLocation(int uFlags, IntPtr szIconFile, int cchMax, IntPtr piIndex, UIntPtr pwFlags);
        //[PreserveSig]
        //uint GetIconLocation(uint uFlags, IntPtr szIconFile, uint cchMax, IntPtr piIndex, UIntPtr pwFlags);
        [PreserveSig]
        uint Extract(string pszFile, uint nIconIndex, ref IntPtr phiconLarge,ref IntPtr phiconSmall, uint nIconSize);
    }

和功能:

    public uint Load(string pszFileName, uint dwMode)//Using IPersistFile
    {
        icon_File = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Icon.bmp");
        tip = "My tool-tip";
        Logger.WriteLog("Load :"+pszFileName+" , "+dwMode.ToString());
        return S_OK;
    }
    public uint GetIconLocation(int uFlags, IntPtr szIconFile, int cchMax, IntPtr piIndex, UIntPtr pwFlags)//Using IExtractIcon and IPersistFile.Load
    {
            try
            {
                IconHandlerReturnFlags Flags;
                Flags = IconHandlerReturnFlags.PerClass | IconHandlerReturnFlags.DontCache | IconHandlerReturnFlags.NotFilename;
                pwFlags = (UIntPtr)Flags;
                Logger.WriteLog("GetIconLocation...");
                return S_OK;
            }
            catch (Exception e)
            {
                Logger.WriteLog("GetIconLocation " + e.Message);
                return S_FALSE;
            }
        }

        public uint Extract(string pszFile, uint nIconIndex, ref IntPtr phiconLarge,ref IntPtr phiconSmall, uint nIconSize)//Using IExtractIcon 
        {
                Logger.WriteLog("Extract...");
    // other code...
}

Load函数正常工作并提供正确的文件名。GetIconLocation也有效。但是在返回后S_OK值提取不会执行...:(

这是在Windows资源管理器中查看两个.myf文件图标后的日志

Load : C:'**********1.Myf , 0
GetIconLocation...
Load : C:'**********2.Myf , 0
GetIconLocation...
Load : C:'**********1.Myf , 0
GetIconLocation...
GetIconLocation...
Load : C:'**********1.Myf , 0
GetIconLocation..

(有时两个GetIconLocation通话没有Load

请有人帮帮我...

为 C# 中的自定义图标创建窗口扩展处理程序

它可以帮助你回答我的问题:(来自微软网站...

实现 IExtractIcon接口接口初始化后,命令行管理程序使用处理程序的 IExtractIcon界面以请求相应的图标。该接口有两种方法:IExtractIcon::GetIconLocation andIExtractIcon::Extract .图标由其位置标识文件系统。这IExtractIcon::GetIconLocation 方法调用以请求此信息。设置文件的 szIconFile 参数名字。如果 中有多个图标该文件,将 piIndex 设置为图标的索引。为两者分配适当的值标记变量。如果你不想指定文件名,或者如果不指定文件名希望命令行管理程序提取图标,设置GIL_NOTFILENAME旗帜中的旗帜参数。您无需分配值为 szIconFile,但处理程序必须在以下情况下提供图标句柄Shell 调用 IExtractIcon::Extract 。如果返回文件名,则命令行管理程序通常尝试从它的缓存。为了防止加载缓存图标,设置GIL_DONTCACHE标记在 pwFlags 参数中。如果缓存图标未加载,命令行管理程序然后调用IExtractIcon::Extract 以请求图标句柄。如果文件和索引由IExtractIcon::GetIconLocation , they传递给 IExtractIcon::Extract in这pszFile 和 nIconIndex 参数,分别。如果提供了文件名,您的处理程序可以将S_FALSE返回到让命令行管理程序提取图标。否则,处理程序必须提取或否则产生大和小图标,并将其 HICON 句柄分配给菲控大和菲康小参数。命令行管理程序将图标添加到它的缓存以加快后续调用处理程序。