ICopyHook 允許開發者建立「複製鉤子」處理程序,在 Shell 執行資料夾/印表機物件的移動、複製、重新命名、刪除前進行驗證。Shell 會呼叫 CopyCallback 方法,回傳值決定是否繼續:IDYES 繼續,IDNO/IDCANCEL 取消。
一個資料夾可安裝多個 Copy Hook,Shell 會依序呼叫,只有全部回傳 IDYES 才會真正執行操作。注意:Hook 只能攔截驗證,無法得知操作最終結果;若需事後通知,需結合 FindFirstChangeNotification/FindNextChangeNotification。
IUnknown 与 ICopyHook。IClassFactory。regsvr32.exe 註冊。HKEY_CLASSES_ROOT\Directory\Shellex\CopyHookHandlers 下建立子鍵,預設值設為元件 CLSID。#define NO_WIN32_LEAN_AND_MEAN
#include
class TCopyHook : public ICopyHook {
public:
TCopyHook(): m_refcnt(0) {}
STDMETHODIMP QueryInterface(REFIID iid, void** ppvObject);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP_(UINT) CopyCallback(HWND hwnd, UINT wFunc, UINT wFlags,
LPCTSTR pszSrcFile, DWORD dwSrcAttribs,
LPCTSTR pszDestFile, DWORD dwDestAttribs);
private:
int m_refcnt;
};
class TClassFactory : public IClassFactory {
public:
TClassFactory(): m_refcnt(0) {}
STDMETHODIMP QueryInterface(REFIID iid, void** ppvObject);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject);
STDMETHODIMP LockServer(BOOL fLock);
private:
int m_refcnt;
};
extern LONG nLocks; // 供 DllCanUnloadNow 使用
// TCopyHook 參考計數與 QueryInterface 略...
UINT __stdcall TCopyHook::CopyCallback(HWND hwnd, UINT wFunc, UINT wFlags,
LPCTSTR pszSrcFile, DWORD dwSrcAttribs,
LPCTSTR pszDestFile, DWORD dwDestAttribs)
{
char szMessage[MAX_PATH+14];
sprintf(szMessage, "對 %s 進行的操作,是否繼續?", pszSrcFile);
return MessageBox(NULL, szMessage, "確認", MB_YESNO | MB_ICONEXCLAMATION);
}
// TClassFactory 實作:CreateInstance 建立 TCopyHook、LockServer 管理 nLocks...
此範例在使用者嘗試移動/刪除資料夾時彈出確認對話框,展示了攔截邏輯的核心。實際應用中可依 wFunc (FO_MOVE, FO_COPY, FO_DELETE, FO_RENAME) 与路徑判斷是否允許。