开发者社区> xumaojun> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

(C#)Windows Shell 外壳编程系列7 - ContextMenu 注册文件右键菜单

简介:
+关注继续查看

(本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢~)

 

接上一节:(C#)Windows Shell 外壳编程系列6 - 执行

 

从本节起,我所要讲述的是对 Windows 系统的“Shell 扩展”。“Shell 扩展”从字面上分两个部分:Shell 与 Extension。Shell 指 Windows Explorer,而Extension 则指由你编写的当某一预先约定好的事件(如在以. doc 为后缀的文件图标上单击右键)发生时由 Explorer 调用执行的代码。因此一个“Shell 扩展”就是一个为 Explorer 添加功能的 COM 对象。 


“Shell 扩展”有很多种类型,每种类型都在各自不同的事件发生时被调用运行,但也有一些扩展的类型和调用情形是非常相似的。
 

 

类型 何时被调用 应该作些什么
Context menu 
扩展处理器
用户右键单击文件或文件夹对象时,
或在一个文件夹窗口中的背景处单击右键时(要求
shell版本为4.71+
添加菜单项到上下文菜单中
Property sheet
扩展处理器
要显示一个文件对象的属性框时 添加定制属性页到属性表中
Drag and drop 
扩展处理器
用户用右键拖放文件对象到文件夹窗口或桌面时 添加菜单项到上下文菜单中
Drop 扩展处理器 用户拖动Shell对象并将它放到一个文件对象上时 任何想要的操作
QueryInfo扩展处理器 (需要shell版本 4.71+) 用户将鼠标盘旋于文件或其他Shell对象的图标上时 返回一个浏览器用于显示在提示框中的字符串

 

 

现在你可能想知道“Shell 扩展”到底是什么样的,不过我还是乐意把我后面所实现的技术效果直接展示出来。以下三副图片分别代表了三种“Shell 扩展”:

 

(1)实现类似 WinRAR 的右键菜单

 

(2)根据文本大小,显示不同的 TXT 文件图标

 

(3)当鼠标移动到 TXT 文件图标上的时候,显示内容预览。

 

好,废话不多说了,赶紧进入今天要讲述的内容: ContextMenu 注册文件右键菜单。

 

对于 WinRAR 所实现的效果,其实叫做上下文菜单。例如我们把扩展关联到 .TXT 文件,当用户右键单击文本文件对象时扩展就会被调用,然后向系统菜单增加菜单项,并响应相应的命令。由此可见,基本上每种 Shell 扩展,都需要做一些几乎一样的事情。

 

初始化接口 
当我们的shell扩展被加载时,Explorer 将调用我们所实现的COM对象的 QueryInterface() 函数以取得一个 IShellExtInit 接口指针。该接口仅有一个方法 Initialize(),其函数原型为:  

 

IShellExtInit原型

 

Explorer 使用该方法传递给我们各种各样的信息.
pidlFolder 是用户所选择操作的文件所在的文件夹的 PIDL 变量. (一个 PIDL [指向ID 列表的指针] 是一个数据结构,它唯一地标识了在Shell命名空间的任何对象, 一个Shell命名空间中的对象可以是也可以不是真实的文件系统中的对象。)
lpdobj 是一个 IDataObject 接口指针,通过它我们可以获取用户所选择操作的文件名。
hKeyProgID 是一个HKEY 注册表键变量,可以用它获取我们的DLL的注册数据。

 

因此我们可以在这个方法中,获取到被右击选择的一个或多个文件/文件夹名。

 

IShellExtInit.Initialize

 

IDataObject 是一个接口,包含了一些获取文件名的方法,后面可以用到。

 

与上下文菜单交互的接口 

一旦 Explorer 初始化了扩展,它就会接着调用 IContextMenu 的方法让我们添加菜单项, 提供状态栏上的提示, 并响应执行用户的选择。IContextMenu 接口定义了以下几个方法:

IContextMenu原型

 

第一个是 QueryContextMenu(), 它让我们可以修改上下文菜单。其参数:

hmenu 上下文菜单句柄。
uMenuIndex 是我们应该添加菜单项的起始位置。
uidFirstCmd 和 uidLastCmd 是我们可以使用的菜单命令ID值的范围。
uFlags 标识了Explorer 调用 QueryContextMenu() 的原因。

 

我们调用该方法,为上下文菜单增加几个菜单项:

 

IContextMenu.QueryContextMenu

 

在状态栏上显示提示帮助

下一个要被调用的IContextMenu 方法是 GetCommandString().。如果用户是在浏览器窗口中右击文本文件,或选中一个文本文件后单击文件菜单时,状态栏会显示提示帮助。我们的 GetCommandString() 函数将返回一个帮助字符串供浏览器显示。

 

IContextMenu.GetCommandString

 

执行用户的选择 

IContextMenu 接口的最后一个方法是 InvokeCommand()。当用户点击我们添加的菜单项时该方法将被调用。其参数:

CMINVOKECOMMANDINFO 结构带有大量的信息, 但我们只关心 lpVerb 和 hwnd 这两个成员。
lpVerb参数有两个作用 – 它或是可被激发的verb(动作)名, 或是被点击的菜单项的索引值。

hwnd 是用户激活我们的菜单扩展时所在的浏览器窗口的句柄。

 

我们可以根据被点击的菜单项索引,来执行相应的操作。

 

IContextMenu.InvokeCommand

 

注册Shell扩展
现在我们已经实现了所有需要的COM接口. 可是我们怎样才能让浏览器使用我们的扩展呢?首先,我们要注册动态库。但仅仅这样是不够的,为了告诉浏览器使用我们的扩展, 我们需要在文本文件类型的注册表键下注册扩展。

(请原谅我未能抽出时间对注册扩展做详细的说明(如果以后有机会会补上),大家可以自行研究)

 

注册扩展


注册动态库

.NET 开发的动态库有些特别,需要在 .NET SDK 中注册

regasm MyContextMenu.dll /CodeBase
反注册则是:regasm /unregister MyContextMenu.dll /CodeBase

 

代码:http://files.cnblogs.com/lemony/MyContextMenu.rar

 

关于代码:代码里面还包括了图标扩展和提示扩展的代码,如果有兴趣,可自行阅读。

 

题外话:还有相当多的关于 Shell 扩展的内容无法一一说明,如果有机会,以后会尽量补上。或大家查阅网上的“Windows Shell扩展编程完全指南”(虽然是VC版的,但内容相当丰富)

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
如何从虚拟机上的linux使用sz命令传输windows大于4G的文件
如何从虚拟机上的linux使用sz命令传输windows大于4G的文件
0 0
Windows与Linux文件互传
Windows与Linux文件互传
0 0
FontForge不识别,WINDOWS报错:mstmc.ttf真的是字体文件吗?
FontForge不识别,WINDOWS报错:mstmc.ttf真的是字体文件吗?
0 0
JDK windows加载字体文件的函数
JDK windows加载字体文件的函数
0 0
WINDOWS对文件签名,算法如何由sha1改为sha256/sha512
WINDOWS对文件签名,算法如何由sha1改为sha256/sha512
0 0
对自己编译的文件(exe/dll)进行签名的实践(Windows)
对自己编译的文件(exe/dll)进行签名的实践(Windows)
0 0
阿里云国际版Windows Server2008系统的虚拟内存设置到数据盘后无法生成MEMORY.DMP文件
本文www.123clouds.com介绍阿里云国际版Windows Server2008系统的虚拟内存设置到数据盘后无法生成MEMORY.DMP文件的解决办法。
0 0
windows下如何列出目录下所有子目录及文件?
windows下如何列出目录下所有子目录及文件?
0 0
windows系统下上传ipa文件到开发者中心(appstore)的方法
windows系统下上传ipa文件到开发者中心(appstore)的方法
0 0
2022最新windows上传ipa文件到app store的方法
2022最新windows上传ipa文件到app store的方法
0 0
+关注
xumaojun
乐于学习与分析
文章
问答
文章排行榜
最热
最新
相关电子书
更多
ECS运维指南之Windows系统诊断
立即下载
TAKING WINDOWS 10 KERNEL
立即下载
《云服务器运维之Windows篇》
立即下载