名词解释
所谓的Shell扩展就是能够添加某种功能到Windows Shell的COM对象。
Windows里有着各种各样的扩展,但关于Shell扩展的原理以及如何编写Shell扩展的文档却很少。现在主要参考codeproject的几个经典例子。
如果你想深入地了解Shell各方面的细节,我特别推荐Dino Esposito的著作《Visual C++ Windows Shell Programming》。
但对于那些没有这本书的,或只对Shell扩展本身感兴趣的朋友,有个编程指南希望能够帮助你理解怎样编写Shell扩展。
该指南假设你理解COM和ATL的基本原理及应用。
主要应用
编程指南中有源码,是基于VC6的,不过再Visual 2005,2010下升级下就可编译通过。如果你想在右键中加入自定义菜单,或在右键属性中加入属性页,
就得用到Shell扩展编程。
实例代码(右键属性扩展改为右键菜单扩展)
如果你是要单纯实现右键菜单,或右键属性,可参考编程指南一步步实现就可以。我这是一种另类的业务需求,假设你的产品中某项功能已经加到
右键属性中,但客户感觉操作麻烦,非要改到右键菜单中。怎么改呢其实很简单。以从codeproject下载的源代码ShellExtGuide5_demo为例。
FileTimeShlExt.h中
class ATL_NO_VTABLE CFileTimeShlExt :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CFileTimeShlExt, &CLSID_FileTimeShlExt>,
public IShellExtInit,
// public IShellPropSheetExt
public IContextMenu
{
...
BEGIN_COM_MAP(CFileTimeShlExt)
COM_INTERFACE_ENTRY(IShellExtInit)
//COM_INTERFACE_ENTRY(IShellPropSheetExt)
COM_INTERFACE_ENTRY(IShellPropSheetExt)
END_COM_MAP()
...
// IShellPropSheetExt
//STDMETHODIMP AddPages(LPFNADDPROPSHEETPAGE, LPARAM);
//STDMETHODIMP ReplacePage(UINT, LPFNADDPROPSHEETPAGE, LPARAM) { return E_NOTIMPL; }
STDMETHODIMP GetCommandString(UINT_PTR, UINT, UINT*, LPSTR, UINT);
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
FileTimeShlExt.rgs 中
NoRemove *
{
NoRemove shellex
{
NoRemove PropertySheetHandlers 改为ContextMenuHandlers
{
{3FCEF010-09A4-11D4-8D3B-D12F9D3D8B02}
}
}
}
接下来在cpp文件中实现新加的三个函数就可以。
难点就是在如何把属性页,在右键单击菜单时,显示出来。
首先要到资源中对Dialog属性进行修改,Border:thin->dialog frame;style:child->popup;System menu:False->true
对Dialog的显示有两种思路:
一、写一个Dialog的实现类如CFileTimeDlg,在InvokeCommand中
加入代码
CFileTimeDlg dlg ();
dlg.doModel();
二、CFileTimeShlExt 多继承一个CDialogImpl,并加入相应的实现
// Construction
enum { IDD =IDD_FILETIME_PROPPAGE};
// Maps
BEGIN_MSG_MAP(CProgressDlg)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
....
END_MSG_MAP()
然后InvokeCommand中加入代码
this->doModel();
一个编译的问题
VS2010 64位版本编译时报错
错误 1 error C2259: “ATL::CComObject<Base>”: 不能实例化抽象类 C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include\atlcom.h 1994
原因:参数类型UINT,64位不兼容
STDMETHODIMP CSimpleShlExt::GetCommandString (
UINT idCmd, UINT uFlags, UINT* pwReserved, LPSTR pszName, UINT cchMax )
第一个参数UINT改为UINT_PTR,其他参数不用改