Windows Shell程式設計實現重疊圖示OverlayIcon
轉載: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
重啟後就可以看到效果了!
出處:https://www.cnblogs.com/chechen/p/8758263.html
=======================================================================================
OverlayIcon 製作流程及注意項
OverlayIcon製作流程及注意項
為了製作類似SVN的圖示覆蓋特效,我確實花了一些時間。目前做到的程度是開發的DLL其Release版本可以在XP、Win7上使用。
第一步:
參考Howto overlay an icon over existing shell objects in 3 easy steps – CodeProject這篇文章,按步驟做。
這一步做完後,編譯會出現: error C2787: “IShellIconOverlayIdentifier”: 沒有與該物件關聯的 GUID ,這樣的錯誤
第二步:
在MyOverlayIcon.h檔案新增
struct _declspec (uuid("987423F4-904A-4ACF-9803-EC28B51C1993"))IShellIconOverlayIdentifier;
//UUID替換為自己工程中的UUID, 這樣編輯將不會出現錯誤了。
第三步:
檢查登錄檔:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\下的項是否超過了15個
如果該鍵含有太多的SubKey那麼也將不會顯示,或者僅在資源管理器的左邊的樹形結構上進行顯示。
第四步:
重啟Explorer程序,然後右鍵“重新整理”。
taskkill /f /im explorer.exe & explorer
第五步:
檢查工程的屬性->配置屬性->C/C++->前處理器->前處理器定義,裡面的值要包含:_ATL_NO_UUIDOF(我不知道為什麼,但是不寫就真的不行)
IShellIconOverlayIdentifier說明三個函式說明:
Shell通過呼叫IShellIconOverlayIdentifier::GetOverlayInfo請求處理程式圖示覆蓋的位置。圖示覆蓋處理程式返回包含覆蓋圖示的檔案的名稱,以及他們在檔案中的索引。然後,Shell新增這些圖示覆蓋到系統圖像列表。
Shell通過呼叫IShellIconOverlayIdentifier::GetPriority來確定圖示覆蓋的優先順序。優先順序值是從0到100的數字,其中100表示最低優先順序。如果有多個圖示覆蓋被特定檔案請求,Shell使用這些值來幫助確定哪個圖示覆蓋將顯示
在繪畫一個物件圖示之前,Shell傳遞物件名稱到每個圖示覆蓋處理程式的IShellIconOverlayIdentifier::IsMemberOf方法。圖示覆蓋處理程式通常與特定檔案分組相關。例如,圖示覆蓋處理程式可能請求一個檔案型別的所有成員的一個覆蓋,就像一個.myp檔名擴充套件的所有檔案。如果處理程式想要他的圖示覆蓋被顯示,它返回S_OK。然後Shell呼叫處理程式IShellIconOverlayIdentifier::GetOverlayInfo方法決定哪個圖示將顯示。
說明:
1.目前不知道如何除錯實現IShellIconOverlayIdentifier介面的DLL。在VS2005下選擇Debug模式,啟動除錯我也輸入了C:\windows\explorer.exe程序,但是提示“無法找到explorer.exe的除錯資訊”。故開發OverlayIcon特效時如何除錯是個問題。
2. 為了能在XP上也執行,需要考慮在VS2005中,專案屬性->配置屬性->常規->ATL的使用選擇“靜態連線到ATL”。
3.在Win7上開發時,可以考慮先關掉UAC,不然效果也有可能無法出現。
出處:https://blog.csdn.net/xiaoqiangxx/article/details/7239298
=======================================================================================
=======================================================================================
=======================================================================================
=======================================================================================