Shell扩展就是对explorer的扩展。
主要分为四个部分:ContexMenu扩展、Property Sheet扩展、Drag and drop扩展、Drop扩展及QueryInfo扩展。
ContextMenu扩展是一种最常用的扩展。当用户右键单击文件或文件夹对象时,或在一个文件夹窗口中的背景处单击右键时,可以将扩展的菜单项加入上下文菜单中,并可响应一定的事件。Now we explain the ContexMenu through a simple project.
There are two interfaces must be implemented --IShellExtInit and IContextMenu.(the <comdef.h>should be include).
Initialize Interface:
-- IShellExtInit:The Explorer will call the function"QueryInterface" of COM object while we load the shell extension, to get IshellExtInit's interface pointer.
There is only one methead in IShellExtInit----Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hKey).
pidlFolder:The current folder's PIDL. pDataObj:It is a IDataObject pointer.We can get the selected files' full path through the pointer. hKey: It can give us the dll's register data.
class ATL_NO_VTABLE CDllShelReg :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CDllShelReg, &CLSID_DllShelReg>,
public IDispatchImpl<IDllShelReg, &IID_IDllShelReg, &LIBID_DLLREGLib>,
public IShellExtInit, // implement the IShellExtInit interface
public IContextMenu
{
public:
CDllShelReg()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_DLLSHELREG)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDllShelReg) //COM_MAP is a macro to implement the QueryInterface().The list
// included by it tell ATL that other client program can get what interfaces
// from our COM Object.
COM_INTERFACE_ENTRY(IDllShelReg)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()
ContextMenu Interface:
After initialize, the Explorer will call the IContextMenu to add the menu item and provide the state's tips atc.
There are three methods in IContextMenu:QueryContextMenu/GetCommandString/InvokeCommand.
---QueryContextMenu(HMENU hmenu , UINT uMenuId, UINT uidFisrt, UINT uidLast, UINT uFlags):
hmenu:contextmenu handle.
uMenuId: The start pos to add our menuitem.
uidFirst/uidLast: The IDs that we can use.
uFlags: We should know one important flag--CMF_DEFAULTONLY. The flag tell the shell that it will retain its default menu items.We cannot add other items to it . And then we return it with MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL,0).
-----GetCommandString(UINT idCmd, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax).
When the user right click the file in explorer or select a file, there are some help strings can show in the state windows.
idCmd : A counter bases on Zero.It indicates which menuitem be selected.
*pwReserved: reserved
pszName: Point to a buffer owned by shell, where we can copy the hlep string to.
cchMax : The buffer size
return: S_OK or E_FAIL
------ InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo). The function will be called when users click our new menuitem.
pcmdInfo: In fact ,all the informations are included in the struct. But ,we only care two items'lpVerd' and 'hwnd'.
'lpVerd' has to functions--verb name or menu index id. 'hwnd'-- the explorer's handle in which activate our exten menu.
about regedit:
HKCR //HKEY_CLASSES_ROOT { NoRemove txtfile { NoRemove ShellEx { NoRemove ContextMenuHandlers { ForceRemove SimpleShlExt = s '{5E2121EE-0300-11D4-8D3B-444553540000}' } } } }
HKCR //HKEY_CLASSES_ROOT
NoRemove // The keyvalue not be delete when unregister the com server
ForceRemove //If the key already has a value, it must be delete when set a new value.