初始化 Shell 擴充處理程式

Shell 擴充處理程序物件的大部分實作是由其類型所決定。 不過,有一些常見的元素。 本主題討論所有Shell擴充處理程式共用的實作層面。

所有 Shell 延伸模組處理程式都是進程元件物件模型 (COM) 物件。 它們必須指派 GUID 並註冊,如 註冊 Shell 擴展處理程序中所述。 它們會實作為 DLL,而且必須匯出下列標準函式:

  • DllMain。 DLL 的標準進入點。
  • DllGetClassObject。 公開對象的類別處理站。
  • DllCanUnloadNow。 COM 會呼叫此函式來判斷物件是否為任何用戶端提供服務。 如果沒有,系統可以卸除 DLL 並釋放相關聯的記憶體。

如同所有 COM 物件,Shell 擴充處理程式必須實作 IUnknown 介面和 類別處理站。 大部分也必須在 Windows XP 或更早版本中實作 IPersistFile 或 IShellExtInit 介面。 這些已由 Windows Vista 中的 IInitializeWithStream、IInitializeWithItem 和 IInitializeWithFile 取代。 Shell 會使用這些介面來初始化處理程式。

IPersistFile 介面必須由下列項目實作:

  • 圖示處理程式
  • 數據處理者
  • 拖放處理程式

IShellExtInit 介面必須由下列項目實作:

  • 快捷選單處理程式
  • 拖放處理程式
  • 屬性表處理程式

本主題的其餘部分會討論下列主題:

實作 IPersistFile

IPersistFile 介面的設計目的是允許從磁碟檔案載入或儲存物件。 除了 IUnknown方法外,它有六個方法,包括其自身的五個方法以及從 IPersist繼承的 GetClassID 方法。 使用 Shell 擴充時,IPersist 只會用來初始化 Shell 擴充處理器物件。 因為通常不需要從磁碟讀取或寫入,只有 GetClassID 和 Load 方法需要非符號實作。

Shell 會先呼叫 GetClassID,而函式會傳回擴充處理程式對象的類別標識碼 (CLSID)。 然後 Shell 會呼叫 Load,並傳入兩個值。 第一個 pszFile是 Unicode 字串,代表 Shell 即將操作的檔案或資料夾的名稱。 第二個是 dwMode,表示檔案存取模式。 因為通常不需要存取檔案,dwMode 通常是零。 方法會視需要儲存這些值,以供稍後參考。

下列代碼段說明一般 Shell 延伸模組處理程式如何實作 GetClassID 和 Load 方法。 其設計目的是要處理 ANSI 或 Unicode。 CLSID_SampleExtHandler是擴充處理程序物件的 GUID,而 CSampleShellExtension 是用來實作介面的類別名稱。 m_szFileName 和 m_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;
}

Infotip 自定義

有兩種方式可以自定義資訊提示。 其中一種方法是實作支援 IQueryInfo 的物件,然後在登錄中適當的子機碼下註冊物件(請參閱下方)。 或者,您可以指定要顯示的固定字串或特定檔案屬性的清單。

若要顯示命名空間延伸模組的固定字串,請在命名空間延伸模組的 CLSID 索引鍵下方建立名為 InfoTip 的子機碼。 將該子機碼的值設定為您想要顯示的字串。

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

若要顯示檔類型的固定字串,請在您想要提供資訊提示的檔類型之 ProgID 索引鍵下,建立一個名為 InfoTip 的子鍵。 將該子機碼的數據設定為您想要顯示的字串。

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

如果您想要 Shell 在特定檔案類型的資訊提示中顯示特定檔案屬性,請在該檔類型的 ProgID 索引鍵下方,建立名為 InfoTip 的子機碼。 將該子機碼的數據設定為以分號分隔的標準屬性名稱或 {fmtid}, pid 組的列表,其中 propname 是標準屬性名稱,且 {fmtid}, pid 是 FMTID/PID 組合。

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

您可以使用下列屬性名稱。

屬性名稱 描述 擷取自
作者 檔的作者 PIDSI_AUTHOR
標題 檔的標題 PIDSI_TITLE
主題 主旨摘要 PIDSI_SUBJECT
評論 文件註解 PIDSI_COMMENT 或資料夾/磁碟驅動器屬性
頁數計算 頁數 PIDSI_PAGECOUNT
名字 易記名稱 標準資料夾檢視
OriginalLocation 源檔的位置 公事包資料夾和回收站資料夾
刪除日期 檔案刪除日期 回收站資料夾
類型 檔案類型 標準資料夾詳細數據檢視
大小 檔案大小 標準資料夾詳細數據檢視
SyncCopyIn 與 OriginalLocation 相同 與 OriginalLocation 相同
改 性 上次修改日期 標準資料夾詳細數據檢視
創建 建立日期 標準資料夾詳細數據檢視
存取 上次存取的日期 標準資料夾詳細數據檢視
InFolder 包含檔案的目錄 文件搜尋結果
排名 搜尋比對的品質 文件搜尋結果
自由空間 可用的儲存空間 磁碟驅動器
訪問次數 瀏覽次數 Favorites 資料夾
屬性 檔案屬性 標準資料夾詳細數據檢視
公司 公司名稱 PIDDSI_COMPANY
類別 檔案類別 PIDDSI_CATEGORY
版權 媒體版權 PIDMSI_COPYRIGHT
HTML資訊提示檔案 HTML 資訊提示檔案 資料夾的 Desktop.ini 檔案

 

登錄 Shell 擴展處理程序