共用方式為


初始化 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 方法需要非符號實作。

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;
}

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}, pidFMTID/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 擴展處理程序