在Windows中,用鼠标右键单击文件或者文件夹时弹出的那个菜单便称为上下文相关菜单。要动态地在上下文相关菜单中增添菜单项,可以通过写Context Menu Handler来实现。比如大家所熟悉的WinZip和UltraEdit等软件都是通过编写Context Menu Handler来动态地向菜单中增添菜单项的。如果系统中安装了WinZip,那么当用右键单击一个名为abc的文件(夹)时,其上下文相关菜单就会有一个名为Add to abc.zip的菜单项。本文要实现的Context Menu Handler与WinZip提供的上下文菜单相似,它将在任意类型文件的上下文菜单中增加一个名为“用写字板打开XXX”(其中XXX为当前选定的文件名称)的菜单项,只要你选择该菜单项,Windows就会启动写字板并打开当前所选的文件   编写Context Menu Handler必须实现IShellExtInit和IContextMenu两个接口。除了IUnknown接口所定义的函数之外,Context Menu Handler还需要用到QueryContextMenu、InvokeCommand和GetCommandString这三个非常重要的成员函数。   (1)QueryContextMenu函数:每当系统要显示一个文件对象的上下文相关菜单时,它首先要调用该函数。为了在上下文相关菜单中添加菜单项,我们在该函数中调用InsertMenu函数。   (2)InvokeCommand函数:当用户选定了某个Context Menu Handler登记过的菜单项后,该函数将会被调用,系统将会传给该函数一个指向LPCMINVOKECOMMANDINFO结构的指针。在该函数中要执行与所选菜单项相对应的操作。   (3)GetCommandString函数:当鼠标指针移到一个上下文相关菜单项上时,在当前窗口的状态条上将会出现与该菜单项相关的帮助信息,此信息就是系统通过调用该函数获取的。   具体编写方法请参阅网上的程序实例,网址为www.pccomputing.com.cn。   3.增添上下文相关菜单项说明   如果要静态地为目录或者某一类文件增添上下文相关菜单项,那么就用不着编写Context Menu Handler,可以通过直接修改Windows注册表来达到此目的。比如,可以将下面的内容存成一个扩展名为.REG的文件,然后双击它将其导入注册表,你会发现所有类型文件的上下文相关菜单中都多了一个名叫“记事本”的菜单项。   REGEDIT4   [HKEY_CLASSES_ROOT\*\shell\记事本]   [HKEY_CLASSES_ROOT\*\shell\记事本\command]   @="notepad.exe\"%1\""   通过比较,很容易发现这两种方式所得结果的差异。通过直接修改注册表来增添菜单项的确比较简单,然而它不具有交互性,所增添的菜单项是静态的,并且所能实现的功能也非常有限。但是Context Menu Handler则不同,它使我们可以根据上下文的具体情况动态地添加菜单项,比如可以判断当前选定的是哪一类文件、是不是文件夹、选定的文件(夹)的个数以及获取被选定文件(夹)的属性。有时,这些信息对于程序很有用,如果需要得到此类信息,并且需要根据不同的上下文来执行不同的操作,那么只好依靠Context Menu Hander来实现。本文的实例中,其动态性体现在仅当用户选定了一个文件时,才会在上下文相关菜单中增添菜单项,并且菜单项的名字随着所选文件名的不同而相应地变化。