HKCR{ NoRemove Folder { NoRemove Shellex { NoRemove PropertySheetHandlers { ForceRemove {1F8F343A-1DE0-4B26-97C9-18A39FFC9880} } } }}
按照外壳的组织结构,文件夹是任何在整个名字空间中可获得的对象和容器。目录是一个包含文件和表示文件系统目录的特殊的文件夹。您也可以将外壳扩展只应用到目录。为此,在前面的脚本中将"Folder"替换为"Directory"即可。
为所有文件夹注册外壳扩展的同时也将定制的页面添加到了某些特殊的文件夹,如:任何驱动器的根文件夹。在desktop.ini文件中,可以将一个描述关联到驱动器根文件夹,但不能改变它的图标。改变缺省的根文件夹图标意味着改变驱动器的图标,只能强行更改系统注册表。以下是驱动器定制图标应该在注册表中存放的位置:
HKLM \Software \Microsoft \Windows \CurrentVersion \Explorer \DriveIcons
在"DriveIcons"键下应该创建一个子键,其名字是表示驱动器的字母。如果想要改变"D"驱动器的图标,就要创建一个子树:
...\DriveIcons \D \DefaultIcon
DefaultIcon的缺省键值必须指向一个用逗号分隔的串,其第一部分十图标文件名,第二部分是图标索引。注意您还可以使用资源的ID号在一个可执行模块中区分图标。如果指定的索引是负数,外壳自动将它翻译成一个资源ID并试图找到匹配的图标。例如:
mylib.dll,-204
用资源ID 204指向图标。图十四显示的是"D"驱动器和为它定制的月亮图标。

图十四 定制驱动器盘符图标
使用彩色图标有助于快速区分文件夹,尤其在完全结构化的和大的驱动器。但另一方面,太多的定制图标反而会引起用户的混乱,并且更难正确区分文件夹。所以应该有选择地使用定制页。
发送到(Send To)
"发送到"是一个特殊的文件夹,Windows 2000将它移到了一个叫"Document and Settings"的文件夹下,这个文件夹是当前用户文件夹。它包含应用程序的快捷键,这些应用程序在命令行接受选中文件夹的名字并处理之。
"发送到"菜单有两个有趣的特性:一个是在菜单项附近显示位图,另一个是打开子菜单项。这个特性已经存在很长时间,但几乎没有那个商业应用使用和开发它们。在上下文外壳扩展中,增加单个菜单项,仰或一个弹出式菜单之间没有实质性差别,不用去调用InsertMenu 和AppendMenu来传递单个项目,只要创建并插入一个弹出式子菜单就可以了。

图十五 定制上下文菜单
在文件夹的上下文菜单中还有另外一个功能就是:创建子文件夹以及从文件夹自身进入命令行,参见图十五。单击"New Folder"菜单项,会弹出一个对话框接受子文件夹名字的输入。为了创建一个新文件夹,可以利用一个很少有人知道的API:MakeSureDirectoryPathExists。它有一个路径名作为参数,顾名思义,这个API检查参数中的所有的目录是否都存在,如果不存在就创建它们。所以您可以用以下的串做参数:
one\two\three
然后用外壳扩展来创建文件夹子树。
至于命令行,要使用Comspec环境变量来获取用户的缺省命令行。如果找不到这个环境变量,那么在Windows 9x中缺省使用command.com命令,NT和Windows 2000中缺省使用cmd.exe命令。用CreateProcess可以指定初始目录。 下面是调用命令行的实现代码:
调用命令行TCHAR szCommand[MAX_PATH] = TEXT("");STARTUPINFO sui;PROCESS_INFORMATION pi;OSVERSIONINFO osi;GetEnvironmentVariable(TEXT("ComSpec"), szCommand, ARRAYSIZE(szCommand));if(!*szCommand){ osi.dwOSVersionInfoSize = sizeof(osi); GetVersionEx(&osi); if(VER_PLATFORM_WIN32_NT == osi.dwPlatformId){ lstrcpy(szCommand, TEXT("cmd.exe")); } else{ lstrcpy(szCommand, TEXT("command.com")); }}//set up the STARTUPINFO structureZeroMemory(&sui, sizeof(sui));sui.cb = sizeof(sui);//create the processCreateProcess( NULL, szCommand, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, szInitialDirectory, &sui, &pi);
从图十五中可以看到,每一个菜单想多显示了一个小位图。这是一种组合了Win32标准的宿主绘画机制和IContextMenu3 接口以后的效果。一个外壳扩展如果想要使用位映图像,必须实现IContextMenu3或IContextMenu2接口。这两个接口都是从标准的IcontextMenu继承而来,并且IContextMenu3是建立在IcontextMenu2之上的接口。这些接口被绑定到外壳的特定版本,但在Windows 2000里,它们已经与Windows外壳称为一体了。今天的应用必须把焦点集中在IContextMenu3上。除了IContextMenu的方法以外, IContextMenu3有一个函数叫做HandleMenuMsg2。在菜单从系统接受的所有消息中,HandleMenuMsg2允许扩展处理其中的四个消息:它们是WM_INITMENUPOPUP、 WM_MENUCHAR,、WM_MEASUREITEM、WM_DRAWITEM。通过处理这些消息,您可以自己绘制菜单项并使用位图和您喜欢的字体。当您用外壳扩展插入被绘制的菜单项时,不要忘了置MF_OWNERDRAW标志位开关。
关于源代码
在本系列文章中,FolderExt工程将系列文章中描述的所有的UI特性都集中在一起。如果能仔细研究其中的代码,您一定能开发出界面更丰富、更吸引人的Windows 2000应用程序。外壳扩展的概念是在Windows 2000操作系统中被加固定型的。其中的新特性(诸如:信息条提示、栏目、清除和搜索处理)大大增强了开发者UI编程的能力。在下一次的文章中,VC知识库将向您提供Windows 2000 UI编程方法中更多的现实可能性,那就是超文本模板(HTT)的应用。