vs2013 windows 覆盖图标实现
实现类似SVN小图标的功能,可以更清晰地给用户显示文件的状态,实现如图效果
一、创建工程
全部选择默认选项
生成如图目录,xxxxPS工程可以删掉,其中Generated Files文件夹里的文件,.def文件,.idl文件都是可以自动生成的,
二、创建类
通过引导创建一个类,工程->add->Class,选择ATL->ATL Simple Object,全部默认选项就可,通过引导来创建的ATL类vs会自动帮你写好idl文件,就不需要自己特意去看这个文件的编写了,你只需要关心自己创建的类就可以(.h和.cpp)。
三、继承IShellIconOverlayIdentifier接口
csdn可查这个接口的基本信息,基本上这个接口就是为了实现覆盖小图标的功能
四、实现接口的三个方法
STDMETHOD(GetOverlayInfo)(LPWSTR pwszIconFile,
int cchMax, int *pIndex, DWORD* pdwFlags);
STDMETHOD(GetPriority)(int* pPriority);
STDMETHOD(IsMemberOf)(LPCWSTR pwszPath, DWORD dwAttrib);
五、基本实现代码
// testicon.h : Declaration of the Ctesticon
#pragma once
#include "resource.h" // main symbols
#include "ATLProject1_i.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif
using namespace ATL;
// Ctesticon
class ATL_NO_VTABLE Ctesticon :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<Ctesticon, &CLSID_testicon>,
public IDispatchImpl<Itesticon, &IID_Itesticon, &LIBID_ATLProject1Lib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IShellIconOverlayIdentifier
{
public:
Ctesticon()
{
}
STDMETHOD(GetOverlayInfo)(LPWSTR pwszIconFile,
int cchMax, int *pIndex, DWORD* pdwFlags);
STDMETHOD(GetPriority)(int* pPriority);
STDMETHOD(IsMemberOf)(LPCWSTR pwszPath, DWORD dwAttrib);
DECLARE_REGISTRY_RESOURCEID(IDR_TESTICON)
BEGIN_COM_MAP(Ctesticon)
COM_INTERFACE_ENTRY(Itesticon)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
public:
};
OBJECT_ENTRY_AUTO(__uuidof(testicon), Ctesticon)
// testicon.cpp : Implementation of Ctesticon
#include "stdafx.h"
#include "testicon.h"
STDMETHODIMP Ctesticon::GetOverlayInfo(
LPWSTR pwszIconFile,
int cchMax,
int* pIndex,
DWORD* pdwFlags)
{
std::wstring picpath = GetPicPath();
wcscpy(pwszIconFile, picpath.c_str()); // ico 文件的路径,用dll资源文件则传入dll路径,pIndex为资源文件的偏移
*pIndex = 0;
*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
return S_OK;
}
STDMETHODIMP Ctesticon::GetPriority(int* pPriority)
{
// 返回优先级,0是最高级,这里的功能我没试过,应该是两个组件同时需要显示的时候,通过这个值去判断显示哪个
*pPriority = 0;
return S_OK;
}
STDMETHODIMP Ctesticon::IsMemberOf(LPCWSTR pwszPath, DWORD dwAttrib)
{
// pwszPath 会传入文件路径,根据这个路径判断该文件是否需要显示图标
if (wcsncmp(pwszPath, L"C:\\test", 7))
return S_FALSE; // 不显示
else
return S_OK; // 显示
}
下面是注册表配置文件
HKCR
{
NoRemove CLSID
{
ForceRemove {C9B4C1A1-CB96-4681-8C4C-0676C88F29A7} = s 'testicon Class'
{
ForceRemove Programmable
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
TypeLib = s '{89DC6A3E-B4AF-476D-9A6C-BDBA1F025E3C}'
Version = s '1.0'
}
}
}
HKLM
{
NoRemove SOFTWARE
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NoRemove ShellIconOverlayIdentifiers
{
ForceRemove '1testico' = s '{C9B4C1A1-CB96-4681-8C4C-0676C88F29A7}'
{
}
}
}
}
}
}
}
}
六、组件安装、卸载
管理员权限运行cmd,执行下面命令,其中[dllpath]是编译生成的dll绝对路径,记得路径中有空格要用双引号
: 安装
regsrv32 "[dllpath]"
: 卸载
regsrv32 /u "[dllpath]"
检查是否安装成功可以去注册表查看
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers
下面图片是SVN的小图标注册表
七、备注
- Windows Explorer Shell 支持的 Overlay Icon 最多 15 个,Windows 自身使用了 4 个,只剩 11 个可扩展使用,Windows 内部就是按图标名称的字母顺序来优先显示的。【参考连接】