最近尤其项目需要想给文件添加一个右键菜单,当且仅当右键该文件的时候,右键菜单显示“XXXXTest”
原本以为添加一个右键菜单是一个很简单的事情,添加一个command命令即可,但是后来发现command有一定局限性,最终采用了shell handler方式
添加右键菜单有两种方式:
- 静态添加,即添加shell+command实现
- 动态添加,即添加Shortcut menu handler实现
- 静态添加
一个command命令可以添加给某一个应用程序关联的文件类型a File Type ProgID 或者某一系统子项Windows Subkey
应用程序注册的关联文件类型
系统默认提供的SubKey
上述添加右键菜单有一个局限性就是没有针对某一个特定文件添加右键菜单,通过上述方式添加的右键菜单都是一类型文件共有
显然我们遇到的问题,微软肯定也收到多类似需求并提供了方法:win7之后的系统可以通过添加特定条件Advanced Query Syntax来满足这类需求
因此我们可以给command添加子健AppliesTo限定我们右键添加的条件,如果一个文件名称中包含exampleText1,那么此右键功能是可以的
通过这种方法有一定的局限性,第一限定性比较强,第二win7之前的系统并不支持例如XP
静态添加右键菜单还有很多技巧,例如级联菜单、shift菜单、以及其他接口方法等,静态添加右键菜单简单方便易维护,具体的可以查看MSDN文档
- 动态添加
有静态方式就有动态方式,动态方式就是通过windows系统外壳接口实现动态添加右键菜单,静态方式简单方便,动态方式灵活复杂,menu handler 可以动态判断是否添加右键菜单,自定义复杂的右键响应功能
实现menu handler之后,explorer加载的时候会调用我们实现的接口,动态添加右键功能以及响应右键功能
menu handler其实是一个COM组件的dll,具体实现后面再讲,网上也有很多类似的资料
实现menu handler主要实现两个接口IShellExtInit和IContextMenu
STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY):初始化接口,可以获取右键目标,自定义是否需要添加右键功能,本例中通过此函数判断目标文件名,如果右键的是我们的对象则添加右键菜单,否则不添加
STDMETHODIMP GetCommandString(UINT_PTR, UINT, UINT*, LPSTR, UINT):系统帮助信息接口,本例中不提供帮助信息直接返回
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO):右键菜单响应接口,当点击右键菜单时执行,本例中我们直接调用第三方exe显示版本信息
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT):右键菜单添加接口,本例中添加一个右键菜单
接口具体用法和参数说明可以查阅MSDN
参看文献:
https://msdn.microsoft.com/zh-cn/library/windows/desktop/cc144169(v=vs.85).aspx
https://docs.microsoft.com/zh-cn/windows/desktop/shell/context-menu-handlers