Lately, I had to implement ICopyHook extension for my project. But, I could not get it working like other normal extensions. I tried searching for sample source code on the web/CodeProject with no success. So, I had no choice but to dig down to get it working. And success was not too far away. Introduction to ICopyHook InterfaceICopyHook handler is a shell extension that determines if a folder or a printer can be moved/copied/renamed or deleted. It works with folder only and not with individual files. ICopyHook should only approve or deny the operation by returning the appropriate value. ICopyHook interface has one method, CopyCallback, that we need to implement as per our liking. ICopyHook is really not the name of the interface, it is defined as follows:#ifdef UNICODE
#define ICopyHook ICopyHookW
#else
#define ICopyHook ICopyHookA
#endif
CopyCallback method in ICopyHookA is defined as:STDMETHOD_(UINT,CopyCallback) (THIS_ HWND hwnd, UINT wFunc, UINT wFlags,
LPCSTR pszSrcFile, DWORD dwSrcAttribs,
LPCSTR pszDestFile, DWORD dwDestAttribs) PURE;
and CopyCallback method in ICopyHookW is defined as:STDMETHOD_(UINT,CopyCallback) (THIS_ HWND hwnd, UINT wFunc, UINT wFlags,
LPCWSTR pszSrcFile, DWORD dwSrcAttribs,
LPCWSTR pszDestFile, DWORD dwDestAttribs) PURE;
So you see, you need to implement the right CopyCallback method for your type of compilation, i.e., for UNICODE or non-UNICODE.Implementing ICopyHookCreate an ATL DLL project. I have named it as CopyHook.
Add a new ATL Object from the Insert menu.
From the category, select Objects, and select Simple Object from the Objects list.
Give a name (I have given it as MyHook). In the Properties, select Threading Model as 'Apartment', and interface as 'Dual'.
Add ICopyHook in the list of derivations of the class.
Collapse
class ATL_NO_VTABLE CMyHook : public ComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyHook, &CLSID_MyHook>,
public ICopyHook, // ICopyHook interface.
public IDispatchImpl<IMyHook, &IID_IMyHook, &LIBID_COPYHOOKLib>
Add the following in the COM Map:
Collapse
BEGIN_COM_MAP(CMyHook)
COM_INTERFACE_ENTRY(IMyHook)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_IID(IID_IShellCopyHook , CMyHook)
END_COM_MAP()
Add the appropriate CopyCallBack method to the class and implement it. My implementation of the CopyCallBack is just to popup dialog.
And of course, include shlobj.h. Read more: Codeproject
#define ICopyHook ICopyHookW
#else
#define ICopyHook ICopyHookA
#endif
CopyCallback method in ICopyHookA is defined as:STDMETHOD_(UINT,CopyCallback) (THIS_ HWND hwnd, UINT wFunc, UINT wFlags,
LPCSTR pszSrcFile, DWORD dwSrcAttribs,
LPCSTR pszDestFile, DWORD dwDestAttribs) PURE;
and CopyCallback method in ICopyHookW is defined as:STDMETHOD_(UINT,CopyCallback) (THIS_ HWND hwnd, UINT wFunc, UINT wFlags,
LPCWSTR pszSrcFile, DWORD dwSrcAttribs,
LPCWSTR pszDestFile, DWORD dwDestAttribs) PURE;
So you see, you need to implement the right CopyCallback method for your type of compilation, i.e., for UNICODE or non-UNICODE.Implementing ICopyHookCreate an ATL DLL project. I have named it as CopyHook.
Add a new ATL Object from the Insert menu.
From the category, select Objects, and select Simple Object from the Objects list.
Give a name (I have given it as MyHook). In the Properties, select Threading Model as 'Apartment', and interface as 'Dual'.
Add ICopyHook in the list of derivations of the class.
Collapse
class ATL_NO_VTABLE CMyHook : public ComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyHook, &CLSID_MyHook>,
public ICopyHook, // ICopyHook interface.
public IDispatchImpl<IMyHook, &IID_IMyHook, &LIBID_COPYHOOKLib>
Add the following in the COM Map:
Collapse
BEGIN_COM_MAP(CMyHook)
COM_INTERFACE_ENTRY(IMyHook)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_IID(IID_IShellCopyHook , CMyHook)
END_COM_MAP()
Add the appropriate CopyCallBack method to the class and implement it. My implementation of the CopyCallBack is just to popup dialog.
And of course, include shlobj.h. Read more: Codeproject