Google
 

将程序添加到资源管理器的右键菜单

添加右键菜单可以用注册表的shell项或shellex项。

1 shell项

我用过的每台电脑都会被我加上:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Folder\shell\command prompt\command]
@="cmd.exe"

即将注册表“HKEY_CLASSES_ROOT\Folder\shell\command prompt\command”的默认值设为“cmd.exe”。这样我就可以从命令行快速进入指定目录。

HKEY_CLASSES_ROOT有很多表示文件类型的键。Folder表示文件夹,*表示所有文件。 在文件类型下增加“shell\提示字符串\command”项,并将该项的值设为对应的命令行。 这样在资源管理器对应文件类型上点右键时,菜单中就会有一个菜单项的内容是“提示字符串”,选择这个菜单项就会执行在command项设置的命令。 再看一个例子:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\dllfile\shell\Register Component\command]
@="regsvr32 \"%L\""

[HKEY_CLASSES_ROOT\dllfile\shell\Unregister Component\command]
@="regsvr32 /u \"%L\""

[HKEY_CLASSES_ROOT\ocxfile\shell\Register Component\command]
@="regsvr32 \"%L\""

[HKEY_CLASSES_ROOT\ocxfile\shell\Unregister Component\command]
@="regsvr32 /u \"%L\""

[HKEY_CLASSES_ROOT\exefile\shell\Register Component\command]
@="\"%L\" /regserver"

[HKEY_CLASSES_ROOT\exefile\shell\Unregister Component\command]
@="\"%L\" /unregserver"

这个例子给类型dllfile、ocxfile、exefile增加了“Register Component”和“Unregister Component”命令。 这样我们可以直接通过右键菜单注册或卸载组件。 在HKEY_CLASSES_ROOT下可以看到.dll、.ocx、.exe的默认值指向了dllfile、ocxfile、exefile。

shell项适合比较简单的命令。如果右键菜单要实现比较复杂的功能,我们就要使用Windows的shell扩展编程接口,即使用shellex项。

2 shellex项

2.1 实现shell扩展的COM组件

UltraEdit的右键菜单用起来很方便。那么它是怎么实现的呢?在注册表里可以看到:

[HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\UltraEdit-32]
@="{b5eedee0-c06e-11cf-8c56-444553540000}"

“{b5eedee0-c06e-11cf-8c56-444553540000}”是一个COM组件的uuid。在“HKEY_CLASSES_ROOT\CLSID”下可以找到

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CLSID\{b5eedee0-c06e-11cf-8c56-444553540000}]
@="UltraEdit"

[HKEY_CLASSES_ROOT\CLSID\{b5eedee0-c06e-11cf-8c56-444553540000}\InProcServer32]
@="C:\\Program Files\\IDM Computer Solutions\\UltraEdit-32\\ue32ctmn.dll"
"ThreadingModel"="Apartment"

ue32ctmn.dll就是UltraEdit提供的实现了shell扩展功能的COM组件。这个COM组件如果实现了IContextMenu接口,就可以增加右键菜单。 菜单项的图标文本是在IContextMenu接口的QueryContextMenu函数中指定的。 用户选择菜单项后,Windows会调用IContextMenu接口的InvokeCommand函数,我们在这个函数中实现菜单对应的功能。

我们通常用ATL实现COM组件。因为VC提供了完善的向导,所以用ATL实现一个COM组件其实并不复杂。 在网上可以找到一篇叫作《Windows Shell扩展编程完全指南》的chm,包含了实现shell扩展编程的详细指导。 这是翻译的文章,chm中也包括了原文(因为转载需要译者同意,我就不提供下载了)。示例代码可以从原文网站下载,我也整理了 一份。使用ALT向导,再仿照示例代码,我们很容易建立自己的工程。 然后在QueryContextMenu和InvokeCommand函数中定制自己的菜单项显示和功能。 可以把《Windows Shell扩展编程完全指南》当作游戏攻略,找到自己感兴趣的部分,照着做就行了。

2.2 添加和移除菜单

添加菜单除了注册组件外,只要在对应文件类型下增加一项“shellex\ContextMenuHandlers\描述性名称”, 并将该项的值设为组件的uuid。uuid是在建立ATL工程时自动生成的。注册组件也是通过在注册表添加一些项目完成的。 移除菜单时只要删除注册表的相应项目就可以了。

请注意,“shellex\ContextMenuHandlers”下的“描述性名称”虽然没什么用,但应该能让用户看明白这个扩展是哪个程序加的。 例如“Beyond Compare 2”就起了一个奇怪的名字,所以被我删掉了。 后来我发现BC2的右键菜单没有了,就在CLSID中找到BC2的dll文件的uuid,然后在“*\shellex\ContextMenuHandlers”加了个 “BC2”项,默认值填上uuid就可以了。

组件相关的注册表项目可以见建立ATL工程时自动生成的rgs文件,以及DllRegisterServer和DllUnregisterServer函数。

以cnbook为例,增加右键菜单需要增加以下注册表项目:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\cnbook]
@="{5BB33E44-519C-42A8-8ABF-81478C57A503}"

[HKEY_CLASSES_ROOT\CLSID\{5BB33E44-519C-42A8-8ABF-81478C57A503}]
@="Shellapi.OpenExt"

[HKEY_CLASSES_ROOT\CLSID\{5BB33E44-519C-42A8-8ABF-81478C57A503}\InProcServer32]
@="D:\\projects\\cnbook\\cnbook\\shellapi.dll"
"ThreadingModel"="Apartment"

[HKEY_CLASSES_ROOT\CLSID\{5BB33E44-519C-42A8-8ABF-81478C57A503}\ProgID]
@="Shellapi.OpenExt"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]
"{5BB33E44-519C-42A8-8ABF-81478C57A503}"="Shellapi.OpenExt"

只要删除这些项目就可以移除菜单。 ProgID就是在插入ATL对象时填写的ATL对象名称。组件路径可以在程序中根据应用程序所在目录确定。

 

Google
 

个人主页留言本我的空间我的程序 fmdd@263.net