初始化殼層延伸模組處理常式

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

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

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

如同所有 COM 物件,Shell 延伸模組處理常式必須實作 IUnknown 介面和 類別處理站。 大部分也必須在 Windows XP 或更早版本中實作 IPersistFileIShellExtInit 介面。 這些由 Windows Vista 中的 IInitializeWithStreamIInitializeWithItemIInitializeWithFile 取代。 Shell 會使用這些介面來初始化處理常式。

IPersistFile介面必須由下列專案實作:

  • 圖示處理常式
  • 資料處理程式
  • 卸載處理常式

IShellExtInit介面必須由下列專案實作:

  • 快捷方式功能表處理常式
  • 拖放處理常式
  • 屬性工作表處理常式

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

實作 IPersistFile

IPersistFile介面的設計目的是要允許從磁片檔案載入或儲存物件。 除了IUnknown之外,它還有六個方法、五個自己的方法,以及繼承自IPersistGetClassID方法。 使用 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索引鍵下方,建立名為InfoTip的子機碼。 將該子機碼的資料設定為您想要顯示的字串。

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 瀏覽次數 我的最愛資料夾
屬性 檔案屬性 標準資料夾詳細資料檢視
公司 公司名稱 PIDDSI_COMPANY
類別 檔類別 PIDDSI_CATEGORY
著作權 媒體著作權 PIDMSI_COPYRIGHT
HTMLInfoTipFile HTML 資訊提示檔案 資料夾Desktop.ini檔案

 

註冊殼層擴充處理常式