[ShellExtension]图标扩展-IShellIconlayIdentifier实现
来源:互联网 发布:软件开发维护招聘 编辑:程序博客网 时间:2024/06/05 14:53
习惯性的先亮源码地址:https://git.oschina.net/xiangmu110/template_IShellIconlayIdentifier
以下讲解的可能与源码不同,但都是一个模版出来的!
下面实现的是在后缀为“.txt”的文件图标上面覆盖一个Star图标。
首先创建一个C++ ATL工程,取名为“ShellIconlayIdentifier”。
将“允许合并代理/存根代码”和“支持MFC”打勾,然后点击完成按钮即可。
工程创建完毕,先不着急编译,因为默认情况下编译后VS会自动注册输出,如果注册时没有管理员权限的话,会提示失败。本人觉得自动注册不好,不便于管理,所以在编译之前先将这个设置关闭。如下。
至此基本的工程创建和设置就完成了,就可以编译试试了。
接下来就是图标扩展的实现过程。
1、添加一个ATL简单对象。
因为是为“.txt”的文件添加覆盖图标,所以我们在简称处填写“TxtExt”,后面的名称均会依据这个简称自动生成。然后点击完成即可。
完成之后就创建了三个文件,“CTxtExt”类的头文件和源文件及其注册表文件,如图。
2、修改代码,实现继承“IShellIconOverlayIdentifier”接口。
// TxtExt.h : CTxtExt 的声明#pragma once#include "resource.h" // 主符号#include "ShellIconlayIdentifier_i.h"#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"#endifusing namespace ATL;// CTxtExtclass ATL_NO_VTABLE CTxtExt : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CTxtExt, &CLSID_TxtExt>, public IDispatchImpl<ITxtExt, &IID_ITxtExt, &LIBID_ShellIconlayIdentifierLib, /*wMajor =*/ 1, /*wMinor =*/ 0>, public IShellIconOverlayIdentifier//添加实现接口{public: CTxtExt() { }DECLARE_REGISTRY_RESOURCEID(IDR_TXTEXT)BEGIN_COM_MAP(CTxtExt) COM_INTERFACE_ENTRY(ITxtExt) 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(TxtExt), CTxtExt)// TxtExt.cpp : CTxtExt 的实现#include "stdafx.h"#include "TxtExt.h"// CTxtExt//pwszPath 为当前文件的全路径STDMETHODIMP CTxtExt::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 CTxtExt::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 CTxtExt::GetPriority(THIS_ _Out_ int * pIPriority){ *pIPriority = 0; return S_OK;}
3、因为Shell扩展是要注册到系统中去的,所以还需要修改“TxtExt.rgs”注册表文件,也可以写在工程生成时自带的“ShellIconlayIdentifier.rgs”的文件中。
首先要取得创建“CTxtExt”时,系统创建的“TxtExt.rgs”中标识这个类的GUID。
然后在上诉两个文件中的任意一个文件中写入如下代码。
HKLM{ NoRemove SOFTWARE { NoRemove Microsoft { NoRemove Windows { NoRemove CurrentVersion { NoRemove Explorer { NoRemove ShellIconOverlayIdentifiers { ForceRemove CTxtExt = s '{3FF1599D-C471-4F69-806D-57EA818677BA}' } } } } } }}
这段代码的意思就是将这个程序注册到资源管理器下的注册表项中。
至此代码修改完成,接下来生成一个!
需要注意的是需要区分系统是X86/X64,如果是X64的系统,请生成X64的程序,要不然不起作用的。
然后将程序中标明的图标的名字“star.ico”的图标与生成的程序放在一个目录。
所有的准备工作已经完成,接下来就是注册这个程序。
以管理员权限打开控制台,然后跳转到程序所在目录。
输入以下命令注册程序。
regsvr32 ShellIconlayIdentifier.dll
注册成功后如下图。
程序虽然注册成功了,但是还没有真正被使用,需要重启资源管理器,可以手动重启下。或在控制台下输入以下重启命令。
taskkill /f /im explorer.exe & explorer
重启后就可以看到效果了!
如图就实现了,仅对我们需要标识的文件添加覆盖图标。
如果想卸载程序的话需要执行以下命令,并且也需要重启资源管理器。
regsvr32 /u ShellIconlayIdentifier.dlltaskkill /f /im explorer.exe & explorer
之后就可以删除这个程序了,要不然这个程序一直被资源管理器占用,是删除不了的。
最后,还有一些小细节提醒一下,微软对这个覆盖图标的启用数量有限制,但注册的时候不会报错,只不过程序不会启用而已,比较坑。。所以我们可以学学360,看人家多怪,因为启用顺序是从第一个开始的,所以360在前面加“ ”即空格,很多个空格。。让他的程序排序靠前,这就使的他的程序不会被忽略掉=。=,简直6翻了,9999。
可以在一个工程中实现多种图标覆盖程序,但是必须新建一个简单对象,然后在新建的简单对象中进行修改。因为是在“IsMemberOf”函数中判断是否是我们需要添加的文件,然后再在“GetOverlayInfo”函数中选择覆盖用的那个图标的,这两个函数之间无法使用成员变量来区分所要添加文件的种类。所以,还是老老实实的一种文件的图标覆盖程序,就对应一个ATL简单对象!
读者如有不懂之处敬请留言,如有不对的地方也请指出,谢谢~
- [ShellExtension]图标扩展-IShellIconlayIdentifier实现
- [ShellExtension]图标扩展-IShellIconlayIdentifier实现
- [ShellExtension]上下文扩展-IContextMenu实现
- [ShellExtension]属性页扩展-IShellPropSheetExt实现
- 树形目录结构 竖线+扩展+收缩 图标的实现
- jquery easyui添加图标扩展
- 手机应用图标的展现扩展方式
- java实现系统托盘图标
- c++实现系统托盘图标
- c++实现系统托盘图标
- 系统托盘图标的实现
- VC实现小图标
- Delphi实现系统托盘图标
- 如何实现托盘图标
- Air实现托盘图标
- VC实现系统托盘图标
- vC++ 系统托盘图标实现
- C#实现托盘图标
- cf#334-B - More Cowbell-二分
- jQuery18(小广告效果,动态创建表格)
- bzoj1050【HAOI2006】旅行comf
- jQuery19(无刷新评论,清空元素)
- 一个前端报表设计器的设计分析
- [ShellExtension]图标扩展-IShellIconlayIdentifier实现
- 数据案例-蓝米手机的精准广告营销
- Flash Builder4.7安装
- 比赛和学习需要,开始网联网方向,很多都不懂,希望自己一步一个脚印,坚持不懈的走下去
- 数据分析-可视化数据分析
- jQuery20(加号计算机,判断按钮是否可用)
- c++中int和string的互转
- 数据分析-淘宝卖家的数据分析
- Spark学习笔记6-Spark分布式搭建(5)——ubuntu下Spark分布式搭建