创建图标标记 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。
1 // MyOverlay.h : Declaration of the CMyOverlay 2 3 #pragma once 4 #include "resource.h" // main symbols 5 6 7 8 #include "Example_i.h" 9 #include <ShlObj.h> 10 11 12 13 #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) 14 #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." 15 #endif 16 17 using namespace ATL; 18 19 20 // CMyOverlay 21 22 class ATL_NO_VTABLE CMyOverlay : 23 public CComObjectRootEx<CComSingleThreadModel>, 24 public CComCoClass<CMyOverlay, &CLSID_MyOverlay>, 25 public IDispatchImpl<IMyOverlay, &IID_IMyOverlay, &LIBID_ExampleLib, 26 /*wMajor =*/ 1, /*wMinor =*/ 0>, 27 public IShellIconOverlayIdentifier 28 { 29 public: 30 CMyOverlay() 31 { 32 } 33 34 DECLARE_REGISTRY_RESOURCEID(IDR_MYOVERLAY) 35 36 37 BEGIN_COM_MAP(CMyOverlay) 38 COM_INTERFACE_ENTRY(IMyOverlay) 39 COM_INTERFACE_ENTRY(IDispatch) 40 COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier) 41 END_COM_MAP() 42 43 44 45 DECLARE_PROTECT_FINAL_CONSTRUCT() 46 47 STDMETHOD(IsMemberOf)(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib); 48 STDMETHOD(GetOverlayInfo)(THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile, 49 int cchMax, _Out_ int * pIndex, _Out_ DWORD * pdwFlags); 50 STDMETHOD(GetPriority)(THIS_ _Out_ int * pIPriority); 51 52 HRESULT FinalConstruct() 53 { 54 return S_OK; 55 } 56 57 void FinalRelease() 58 { 59 } 60 61 public: 62 63 64 65 }; 66 67 OBJECT_ENTRY_AUTO(__uuidof(MyOverlay), CMyOverlay)
MyOverlay.h
6、根据 MSDN 实现该 Class。
1 // MyOverlay.cpp : Implementation of CMyOverlay 2 3 #include "stdafx.h" 4 #include "MyOverlay.h" 5 #include <WinBase.h> 6 #pragma comment(lib, "Kernel32.lib") 7 8 // CMyOverlay 9 10 STDMETHODIMP CMyOverlay::IsMemberOf(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib) 11 { 12 if (_tcscmp(pwszPath, L"test") == 0) 13 { 14 return S_OK; 15 } 16 else 17 { 18 return S_FALSE; 19 } 20 } 21 22 STDMETHODIMP CMyOverlay::GetOverlayInfo( 23 THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile, 24 int cchMax, 25 _Out_ int * pIndex, 26 _Out_ DWORD * pdwFlags) 27 { 28 29 GetModuleFileNameW(_AtlBaseModule.GetModuleInstance(), pwszIconFile, cchMax); 30 31 *pIndex = 0; 32 33 *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX; 34 35 return S_OK; 36 } 37 38 STDMETHODIMP CMyOverlay::GetPriority(THIS_ _Out_ int * pIPriority) 39 { 40 *pIPriority = 0; 41 42 return S_OK; 43 }
MyOverlay.cpp
7、在 .rgs 文件中添加注册表信息,确保各 GUID 与 .idl 文件中的一致。
1 HKCR 2 { 3 NoRemove CLSID 4 { 5 ForceRemove {29913677-1662-46C5-8645-16F84DA6F438} = s ‘MyOverlay Class‘ 6 { 7 ForceRemove Programmable 8 InprocServer32 = s ‘%MODULE%‘ 9 { 10 val ThreadingModel = s ‘Apartment‘ 11 } 12 TypeLib = s ‘{942F4DBB-4667-4767-A35B-52F32F623C63}‘ 13 Version = s ‘1.0‘ 14 } 15 } 16 } 17 18 HKLM 19 { 20 NoRemove SOFTWARE 21 { 22 NoRemove Microsoft 23 { 24 NoRemove Windows 25 { 26 NoRemove CurrentVersion 27 { 28 NoRemove Explorer 29 { 30 NoRemove ShellIconOverlayIdentifiers 31 { 32 ForceRemove ‘ MyOverlay‘ = s ‘{29913677-1662-46C5-8645-16F84DA6F438}‘ 33 { 34 } 35 } 36 } 37 } 38 } 39 } 40 } 41 }
8、Build Project 后通过 cmd.exe 注册或解注册生成的 .dll 文件。重启 explorer.exe 后生效。
9、由于 slots 数量有限,检查在注册表中添加的子项是否在有效范围内(目前为前15个)。可采用在子项名称前添加空格的方式将其位置提前。
10、查看效果如下图所示。
参考网址:http://www.codeproject.com/Articles/7484/How-to-overlay-an-icon-over-existing-shell-objects
—————————————————————————————————————
本文为本人原创,如需转载请注明出处。