zoukankan      html  css  js  c++  java
  • Windows Shell编程实现重叠图标IconOverlay

    转载:https://www.codeproject.com/Articles/7484/How-to-overlay-an-icon-over-existing-shell-objects

    转载:https://blog.csdn.net/u012741077/article/details/50641518

    系统默认的:                                                                                              贴上图标后:

                                                                                    

    第一步:新建一个ATL项目,输入工程名:TxtInfo,具体如下图:

    第二步:点击next

    第三步:应用类型选择动态库链接(DLL),同时勾选 允许合并代理/存根代码和支持MFC,最后点击Finish。

    第四步:新建一个ATL简单对象(英文版的VS为ATLSimple Object)

     

    单击 Add,在第二页面中, 在Short Name编辑框中输入TxtShlExt,点击 Finish.

    第五步:开始我们需要添加IShellIconOverlayIdentifier到CTxtShlExt实现的接口列表中.打开 TxtShlExt.h, 并添加如下代码:

    class ATL_NO_VTABLE CTxtShlExt :
        public CComObjectRootEx<CComSingleThreadModel>,
        public CComCoClass<CTxtShlExt, &CLSID_TxtShlExt>,
        public IDispatchImpl<ITxtShlExt, &IID_ITxtShlExt, &LIBID_IconOverlayLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
        public IShellIconOverlayIdentifier//添加实现接口
    {
    public:
        CTxtShlExt()
        {
        }
    
    DECLARE_REGISTRY_RESOURCEID(IDR_TXTSHLEXT)
    
    
    BEGIN_COM_MAP(CTxtShlExt)
        COM_INTERFACE_ENTRY(ITxtShlExt)
        COM_INTERFACE_ENTRY(IDispatch)
        COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier)//添加接口入口
    END_COM_MAP()
    
    
    
        DECLARE_PROTECT_FINAL_CONSTRUCT()
    
        HRESULT FinalConstruct()
        {
            return S_OK;
        }
    
        void FinalRelease()
        {
        }
    
    public:
        //实现接口的三个函数
        STDMETHOD(GetPriority(THIS_ _Out_ int * pIPriority));
        STDMETHOD(IsMemberOf(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib));
        STDMETHOD(GetOverlayInfo(THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile, int cchMax, _Out_ int * pIndex, _Out_ DWORD * pdwFlags));
    
    
    };
    
    OBJECT_ENTRY_AUTO(__uuidof(TxtShlExt), CTxtShlExt)

    TxtShlExt.cpp

    //pwszPath 为当前文件的全路径
    STDMETHODIMP CTxtShlExt::IsMemberOf(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib)
    {
        HRESULT hRef = S_FALSE;
    
        wchar_t* fileClass = _wcsdup(wcsrchr(pwszPath, '.'));
        if (fileClass != NULL)
        {
            if (_wcsicmp(fileClass, L".txt") == 0)
            {//判断是否是txt后缀的文件
                hRef = S_OK;
            }
        }
    
        free(fileClass);
        //如果是符合要求的文件,就返回S_OK
        return hRef;
    }
    
    //pwszIconFile 用于设置图标文件的路径,路径长度不能超过cchMax个字符。
    //pIndex 用于设置图标覆盖的先后顺序
    STDMETHODIMP CTxtShlExt::GetOverlayInfo(THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile, int cchMax, _Out_ int * pIndex, _Out_ DWORD * pdwFlags)
    {
        WCHAR *buff = new WCHAR[cchMax];
        //获取当前程序的路径,而不是调用该程序的程序的路径,因为调用该程序的是资源管理器(explorer.exe),直接过去路径的话,获取的是资源管理器的路径。
        GetModuleFileNameW(_AtlBaseModule.GetModuleInstance(), buff, cchMax);
    
        WCHAR *nChar = wcsrchr(buff, L'\');
        if (nChar != NULL)
        {//写入当前程序路径下的图标的名字
            wcscpy_s(nChar, cchMax - wcslen(buff), L"\star.ico");
            wcscpy_s(pwszIconFile, cchMax, buff);
        }
    
        //设置顺序
        *pIndex = 0;
    
        //标识所修改过的数据pwszIconFile 与 pIndex
        *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
    
        free(buff);
        //完成返回S_OK
        return S_OK;
    }
    
    STDMETHODIMP CTxtShlExt::GetPriority(THIS_ _Out_ int * pIPriority)
    {
        *pIPriority = 0;
        return S_OK;
    }

    第六步:注册COM接口

    方式一:HKLM内容加入TxtShlExt.rgs中

    编辑TxtShlExt.rgs文件

    方式二:HKLM内容加入IconOverlay.rgs中

    编辑IconOverlay.rgs

     

    这段代码的意思就是将这个程序注册到资源管理器下的注册表项中。

    需要注意的是需要区分系统是X86/X64,如果是X64的系统,请生成X64的程序,要不然不起作用的。

     然后将程序中标明的图标的名字“star.ico”的图标与生成的程序放在一个目录。

    用命令行注册COM :regsvr32 dll的绝对路径

    注:必须以管理员运行cmd

    卸载COM: regsvr32 /u dll的绝对路径

     

    程序虽然注册成功了,但是还没有真正被使用,需要重启资源管理器,可以手动重启下。或在控制台下输入以下重启命令。

    taskkill /f /im explorer.exe & explorer

    重启后就可以看到效果了!

  • 相关阅读:
    上海上传数据重复-sftp端口关闭
    探索对象池技术
    java对象池commons-pool-1.6详解(一)
    SSH 协议的 ssh StrictHostKeyChecking
    FTP、FTPS和SFTP
    android 模拟器无法ping通主机
    Android中判断网络连接是否可用及监控网络状态
    Android模拟器怎么配置网络连通
    Android Studio调试报错am startservice
    Jni的Jclass JmethodID JfrieldID的差异
  • 原文地址:https://www.cnblogs.com/chechen/p/8758263.html
Copyright © 2011-2022 走看看