初始化 Shell 扩展处理程序

Shell 扩展处理程序对象的大部分实现由其类型决定。 但是,存在一些常见元素。 本主题讨论由所有 Shell 扩展处理程序共享的实现的那些方面。

所有 Shell 扩展处理程序都是进程内组件对象模型 (COM) 对象。 必须为其分配 GUID 并按照注册 Shell 扩展处理程序中所述进行注册。 它们作为 DLL 实现,必须导出以下标准函数:

  • DllMain。 DLL 的标准入口点。
  • DllGetClassObject。 公开对象的类工厂。
  • DllCanUnloadNow。 COM 调用此函数以确定对象是否为任何客户端提供服务。 否则,系统可以卸载 DLL 并释放关联的内存。

与所有 COM 对象一样,Shell 扩展处理程序必须实现 IUnknown 接口和 类工厂。 大多数还必须在 Windows XP 或更早版本中实现 IPersistFileIShellExtInit 接口。 这些内容被 Windows Vista 中的 IInitializeWithStreamIInitializeWithItemIInitializeWithFile 所取代。 Shell 使用这些接口来初始化处理程序。

IPersistFile 接口必须通过以下方式实现:

  • 图标处理程序
  • 数据处理程序
  • 删除处理程序

IShellExtInit 接口必须由以下项实现:

  • 快捷菜单处理程序
  • 拖放处理程序
  • 属性表处理程序

本主题的其余部分将讨论以下主题:

实现 IPersistFile

IPersistFile 接口旨在允许从磁盘文件加载或保存到对象。 除了 IUnknown 之外,它还具有六种方法(其自己的五种方法)以及它从 IPersist 继承的 GetClassID 方法。 使用 Shell 扩展时, IPersist 仅用于初始化 Shell 扩展处理程序对象。 由于通常不需要从磁盘读取或写入磁盘,因此只有 GetClassIDLoad 方法需要非ken 实现。

Shell 首先调用 GetClassID ,函数 (扩展处理程序对象的 CLSID) 返回类标识符。 然后,Shell 调用 Load 并传入两个值。 第一个 是 pszFile,是一个 Unicode 字符串,其中包含 Shell 要操作的文件或文件夹的名称。 第二个是 dwMode,它指示文件访问模式。 由于通常不需要访问文件, 因此 dwMode 通常为零。 方法根据需要存储这些值,供以后参考。

以下代码片段演示了典型的 Shell 扩展处理程序如何实现 GetClassIDLoad 方法。 它旨在处理 ANSI 或 Unicode。 CLSID_SampleExtHandler是扩展处理程序对象的 GUID,CSampleShellExtension 是用于实现接口的类的名称。 m_szFileNamem_dwMode变量是专用变量,用于存储文件的名称和访问标志。

class CSampleShellExtension : public IPersistFile
{
    // Method declarations not included

    private:
    WCHAR m_szFileName[MAX_PATH];    // The file name
    DWORD m_dwMode;                  // The file access mode
}

IFACEMETHODIMP CSampleShellExtension::GetClassID(__out CLSID *pCLSID)
{
    *pCLSID = CLSID_SampleExtHandler;
}

IFACEMETHODIMP CSampleShellExtension::Load(PCWSTR pszFile, DWORD dwMode)
{
    m_dwMode = dwMode;
    return StringCchCopy(m_szFileName, ARRAYSIZE(m_szFileName), pszFile); 
}

// The implementation sample is continued in the next section.

实现 IShellExtInit

除了 IUnknown 之外,IShellExtInit 接口只有一种方法 IShellExtInit::Initialize 方法具有三个参数,Shell 可以使用这些参数传递各种类型的信息。 传入的值取决于处理程序的类型,有些值可以设置为 NULL

  • pidlFolder 保存指向 PIDL) (项标识符列表的文件夹指针。 这是绝对 PIDL。 对于属性表扩展,此值为 NULL。 对于快捷菜单扩展,它是包含显示其快捷菜单的项的文件夹的 PIDL。 对于非默认拖放处理程序,它是目标文件夹的 PIDL。
  • pDataObject 保存指向数据对象的 IDataObject 接口的指针。 数据对象保存 CF_HDROP格式的 一个或多个文件名。
  • hRegKey 保存文件对象或文件夹类型的注册表项。

IShellExtInit::Initialize 方法根据需要存储文件名、IDataObject 指针和注册表项,以供以后使用。 以下代码片段演示 了 IShellExtInit::Initialize 的实现。 为简单起见,此示例假定数据对象仅包含单个文件。 通常,数据对象可能包含多个文件,其中每个文件都需要提取。

// This code continues the CSampleShellExtension sample shown in the
// "Implementing IPersistFile" section above.

class CSampleShellExtension : public IShellExtInit
{
    // Method declarations not included
    
    private:
    // IDList of the folder for extensions invoked on the folder, such as 
    // background context menu handlers or nondefault drag-and-drop handlers. 
    PIDLIST_ABSOLUTE m_pidlFolder;
    
    // The data object contains an expression of the items that the handler is 
    // being initialized for. Use SHCreateShellItemArrayFromDataObject to 
    // convert this object to an array of items. Use SHGetItemFromObject if you
    // are only interested in a single Shell item. If you need a file system
    // path, use IShellItem::GetDisplayName(SIGDN_FILESYSPATH, ...).
    IDataObject *m_pdtobj;
    
    // For context menu handlers, the registry key provides access to verb 
    // instance data that might be stored there. This is a rare feature to use 
    // so most extensions do not need this variable.
    HKEY m_hRegKey;             
}
    
// This method must be very efficient. Do not do any unnecessary work here.
// Use Initialize to acquire resources that will be used later.

IFACEMETHODIMP CSampleShellExtension::Initialize(__in_opt PCIDLIST_ABSOLUTE pidlFolder,
                                                 __in_opt IDataObject *pDataObject, 
                                                 __in_opt HKEY hRegKey) 
{ 
    // In some cases, handlers are initialized multiple times. Therefore, 
    // clear any previous state here.
    CoTaskMemFree(m_pidlFolder);
    m_pidlFolder = NULL;
    
    if (m_pdtobj)
    { 
        m_pdtobj->Release(); 
    }
    
    if (m_hRegKey)
    {
        RegCloseKey(m_hRegKey);
        m_hRegKey = NULL;
    }
    
    // Capture the inputs for use later.
    HRESULT hr = S_OK;
    
    if (pidlFolder)
    {
        m_pidlFolder = ILClone(pidlFolder);   // Make a copy to use later.
        hr = m_pidlFolder ? S_OK : E_OUTOFMEMORY;
    }
    
    if (SUCCEEDED(hr))
    {
        // If a data object pointer was passed into the method, save it and
        // extract the file name. 
        if (pDataObject) 
        { 
            m_pdtobj = pDataObject; 
            m_pdtobj->AddRef(); 
        }
    
        // It is uncommon to use the registry handle, but if you need it,
        // duplicate it now.
        if (hRegKey)
        {
            LSTATUS const result = RegOpenKeyEx(hRegKey, NULL, 0, KEY_READ, &m_hRegKey); 
            hr = HRESULT_FROM_WIN32(result);
        }
    }
    
    return hr;
}

信息提示自定义

可通过两种方式自定义信息提示。 一种方法是实现支持 IQueryInfo 的对象,然后在注册表中的适当子项下注册该对象, (请参阅下面的) 。 或者,可以指定要显示的固定字符串或特定文件属性的列表。

若要显示命名空间扩展的固定字符串,请在命名空间扩展的 CLSID 键下创建名为 InfoTip 的子项。 将该子项的数据设置为要显示的字符串。

HKEY_CLASSES_ROOT
   CLSID
      {CLSID}
         InfoTip = InfoTip string for your namespace extension

若要显示某个文件类型的固定字符串,请在要为其提供信息提示的文件类型的 ProgID 键下面创建一个名为“信息提示”的子项。 将该子项的数据设置为要显示的字符串。

HKEY_CLASSES_ROOT
   ProgID
      InfoTip = InfoTip string for all files of this type

如果希望 Shell 在特定文件类型的信息提示中显示某些文件属性,请在该文件类型的 ProgID 键下创建一个名为 InfoTip 的子项。 将该子项的数据设置为规范属性名称或 {fmtid} 的分号分隔列表,其中 propname 是规范属性名称的 pid 对 ,而 {fmtid},pidFMTID/PID 对

HKEY_CLASSES_ROOT
   ProgID
      InfoTip = propname;propname;{fmtid},pid;{fmtid},pid

可以使用以下属性名称。

属性名称 说明 检索自
作者 文档的作者 PIDSI_AUTHOR
标题 文档的标题 PIDSI_TITLE
主题 主题摘要 PIDSI_SUBJECT
评论 文档注释 PIDSI_COMMENT 或文件夹/驱动器属性
PageCount 页数 PIDSI_PAGECOUNT
名称 友好名称 标准文件夹视图
OriginalLocation 原始文件的位置 公文包文件夹和回收站文件夹
DateDeleted 删除日期文件 回收站文件夹
类型 文件类型 标准文件夹详细信息视图
大小 文件大小 标准文件夹详细信息视图
SyncCopyIn 与 OriginalLocation 相同 与 OriginalLocation 相同
修改时间 上次修改日期 标准文件夹详细信息视图
创建 创建日期 标准文件夹详细信息视图
已访问 上次访问日期 标准文件夹详细信息视图
InFolder 包含文件的目录 文档搜索结果
级别 搜索匹配的质量 文档搜索结果
FreeSpace 可用存储空间 磁盘驱动器
NumberOfVisits 访问次数 收藏夹文件夹
特性 文件属性 标准文件夹详细信息视图
Company 公司名称 PIDDSI_COMPANY
类别 文档类别 PIDDSI_CATEGORY
版权信息 媒体版权 PIDMSI_COPYRIGHT
HTMLInfoTipFile HTML 信息提示文件 文件夹的Desktop.ini文件

 

注册 Shell 扩展处理程序