快捷菜单处理程序和多个谓词的最佳做法

本主题的组织方式如下:

最佳方案

静态谓词是实现的最简单谓词,并提供丰富的功能。 强烈建议使用静态谓词方法之一实现谓词。

谓词实现的最佳做法

以下列表表示谓词实现的最佳做法:

  • 始终选择满足需求的最简单的谓词方法。
  • 尽可能使用静态谓词方法。
  • 不要在 UI 线程上执行资源密集型操作或 I/O。 IShellExtInit::InitializeIContextMenu::QueryContextMenu 在他们执行的工作中都需要非常保守。 IContextMenu::InvokeCommand 必须在另一个进程中执行,或者必须创建新线程以避免阻止调用方。
  • 前缀谓词与独立软件供应商 (ISV) 名称,如下所示 ISVName.verb。 使用非限定名称可能会导致与选择相同谓词名称的多个 ISV 冲突。
  • 始终使用特定于应用程序的 ProgID。 由于某些项类型不使用此映射,因此需要供应商唯一的名称。
  • 将 UI 相对于调用方法定位,但不在调用方线程上运行。
  • 不接受传递给 IContextMenu::InvokeCommand 方法的规范谓词S_OK返回值 这样做会导致调用实际谓词实现失败,并返回规范谓词的失败代码。 如果不支持规范谓词,则在遇到非零 HIWORD(lpVerb) 值时返回失败。
  • 避免将 rundll32.exe 用作谓词的主机。
  • 实现 IContextMenu::QueryContextMenu 时,请务必使用 ResultFromShort 宏通过 HRESULT 值返回已添加到菜单中的谓词数。
  • 如果在以下注册表项条目之一上注册,请谨慎行事,并确保在最具体的类型上注册处理程序,以减少可能意外的后果:
    • HKEY_CLASSES_ROOT\*
    • HKEY_CLASSES_ROOT\AllFileSystemObjects
    • HKEY_CLASSES_ROOT\Folder
    • HKEY_CLASSES_ROOT\Directory
  • 仅当预期可能需要更改快捷菜单中的默认谓词时,才设置 MayChangeDefaultMenu 键。 如果处理程序未更改默认谓词,则不应设置此键,因为这样做会导致系统不必要地加载 DLL。
  • 尽量减少在 IShellExtInit::Initialize执行的工作。 对于快捷菜单处理程序,捕获传递给 IShellExtInit::Initialize 的数据对象,然后在 IContextMenu::QueryContextMenuIContextMenu::InvokeCommand 中对其进行处理。

多个选择谓词的最佳做法

由于多选谓词方案中的项数可能很大,因此请务必考虑动词实现的性能影响。 例如,当用户在包含大量项的范围上搜索“*”,然后单击“ 选”并右键单击时,该谓词会显示一个可以包含数千个项目的选择。 因此,谓词只应考虑所选内容中的第一项和总体项计数。 第一项定义为视图顶部的项,或用户第一次右键单击的项。

在 Windows 7 及更高版本中,查询快捷菜单时传递给谓词的项目数限制为 16。 然后,在调用该谓词时重新创建并重新初始化该谓词的完整选择。

在某些情况下,可以考虑少量固定项。 例如,“差异”谓词只考虑前两项。 通常,无需测试所选内容中的每个项目,以查看它是否为特定类型,或查询所选内容中每个项的属性。 请看第一个项目,确定是否适合添加谓词。

异类选择

假设未指定的项可由谓词处理,乐观谓词会自动添加到多选事例中。 相比之下,当选定内容包含未指定的项时,不会添加悲观谓词,并且仅在项数较小的情况下添加。

玩家样式谓词应保持乐观,并无提示地跳过未处理的项。 如果无法对项目执行操作可能会导致数据丢失或混淆,则谓词应警告用户无法处理的项目。 例如,“backup”谓词应指示某些项无法备份。

为快捷菜单选择静态或动态谓词

创建快捷菜单处理程序

使用动态谓词自定义快捷菜单

快捷(上下文)菜单和快捷菜单处理程序

谓词和文件关联

快捷菜单参考