创建图标标记 Handlers (续)
1、新建一个ATL Project。
2、建议将 Project Property 中 Linker – General - “Register Output” 设为 no,C/C++ - “Code Generation” - “Runtime Library” 设为 /MTd。
3、在 Solution Explorer 中右键 Add Class,选择 ATL Simple Object。并在弹出的对话框中为该 Class 命名。
4、添加完成后建议 Build 一下 Project,MIDL compiler 将根据 .idl 文件生成 IIDs and CLSIDs。
5、切换到新增 Class 的 .h 文件中,使其继承接口 IShellIconOverlayIdentifier。
// MyOverlay.h : Declaration of the CMyOverlay #pragma once
#include "resource.h" // main symbols #include "Example_i.h"
#include <ShlObj.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; // CMyOverlay class ATL_NO_VTABLE CMyOverlay :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyOverlay, &CLSID_MyOverlay>,
public IDispatchImpl<IMyOverlay, &IID_IMyOverlay, &LIBID_ExampleLib,
/*wMajor =*/ , /*wMinor =*/ >,
public IShellIconOverlayIdentifier
{
public:
CMyOverlay()
{
} DECLARE_REGISTRY_RESOURCEID(IDR_MYOVERLAY) BEGIN_COM_MAP(CMyOverlay)
COM_INTERFACE_ENTRY(IMyOverlay)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier)
END_COM_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct()
{
return S_OK;
} void FinalRelease()
{
} public:
STDMETHOD(IsMemberOf)(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib);
STDMETHOD(GetOverlayInfo)(THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile,
int cchMax, _Out_ int * pIndex, _Out_ DWORD * pdwFlags);
STDMETHOD(GetPriority)(THIS_ _Out_ int * pIPriority); }; OBJECT_ENTRY_AUTO(__uuidof(MyOverlay), CMyOverlay)
MyOverlay.h
6、根据 MSDN 实现该 Class。
// MyOverlay.cpp : Implementation of CMyOverlay #include "stdafx.h"
#include "MyOverlay.h"
#include <WinBase.h>
#pragma comment(lib, "Kernel32.lib") // CMyOverlay STDMETHODIMP CMyOverlay::IsMemberOf(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib)
{
if (_tcscmp(pwszPath, L"test") == )
{
return S_OK;
}
else
{
return S_FALSE;
}
} STDMETHODIMP CMyOverlay::GetOverlayInfo(
THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile,
int cchMax,
_Out_ int * pIndex,
_Out_ DWORD * pdwFlags)
{ GetModuleFileNameW(_AtlBaseModule.GetModuleInstance(), pwszIconFile, cchMax); *pIndex = ; *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX; return S_OK;
} STDMETHODIMP CMyOverlay::GetPriority(THIS_ _Out_ int * pIPriority)
{
*pIPriority = ; return S_OK;
}
MyOverlay.cpp
7、在 .rgs 文件中添加注册表信息,确保各 GUID 与 .idl 文件中的一致。
HKCR
{
NoRemove CLSID
{
ForceRemove {--46C5--16F84DA6F438} = s 'MyOverlay Class'
{
ForceRemove Programmable
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
TypeLib = s '{942F4DBB-4667-4767-A35B-52F32F623C63}'
Version = s '1.0'
}
}
} HKLM
{
NoRemove SOFTWARE
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NoRemove ShellIconOverlayIdentifiers
{
ForceRemove ' MyOverlay' = s '{29913677-1662-46C5-8645-16F84DA6F438}'
{
}
}
}
}
}
}
}
}
8、Build Project 后通过 cmd.exe 注册或解注册生成的 .dll 文件。重启 explorer.exe 后生效。
9、由于 slots 数量有限,检查在注册表中添加的子项是否在有效范围内(目前为前15个)。按下Win+R键,通过运行对话框打开regedit.exe,按HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers的顺序依次展开或直接Ctrl+F查找到MyOverlay项。可采用在.rgs文件中的子项名称前添加空格的方式将其位置提前。
10、查看效果如下图所示。
参考网址:http://www.codeproject.com/Articles/7484/How-to-overlay-an-icon-over-existing-shell-objects
—————————————————————————————————————
本文为本人原创,如需转载请注明出处。