實作資料夾檢視
Windows Shell 提供資料夾檢視的預設實作,這稱為 DefView,因此您可以避免實作自己的命名空間延伸模組的大部分工作。 由於某些檢視功能無法透過自訂檢視來達成,因此通常建議使用預設系統資料夾檢視物件來取代自訂檢視。 如需詳細資訊,請參閱 SHCreateShellFolderView。 本主題的其餘部分討論如何實作不支援較新檢視功能的自訂資料夾檢視。
不同于樹狀檢視,Windows 檔案總管不會管理資料夾檢視的內容。 相反地,資料夾檢視視窗會裝載資料夾物件所提供的子視窗。 資料夾物件負責建立資料夾檢視物件,以在子視窗中顯示資料夾的內容。
實作資料夾檢視物件的索引鍵是 IShellView 介面。 Windows 檔案總管會使用此介面來與資料夾檢視物件通訊。 在顯示資料夾檢視之前,Windows 檔案總管會呼叫資料夾物件的 IShellFolder::CreateViewObject 方法,並將 riid 設定為 IID_IShellView。 建立資料夾檢視物件,並傳回其 IShellView 介面。 然後,資料夾檢視物件必須建立資料夾檢視視窗的子視窗,並使用子視窗來顯示資料夾內容的相關資訊。
除了控制資料的顯示方式之外,延伸模組也可以自訂 Windows 檔案總管的一些功能。 例如,延伸模組可以將專案新增至工具列或功能表列,或顯示狀態列的資訊。
資料夾檢視物件
資料夾檢視物件是元件物件模型 (COM) 物件,會公開 IShellView 介面。 此物件負責:
- 建立資料夾檢視視窗的子視窗,並使用它來顯示資料夾的內容。
- 處理與 Windows 檔案總管的通訊。
- 將資料夾特定的命令新增至 Windows 檔案總管功能表列和工具列,並在選取這些命令時處理這些命令。
- 管理使用者與資料夾檢視視窗的互動,例如顯示快捷方式功能表或處理拖放作業。
本檔討論前三個主題。 因為使用者與資料夾檢視的互動是在子視窗內進行,所以您的資料夾檢視物件會負責處理它,就像任何其他視窗一樣。
Windows 檔案總管會呼叫資料夾物件的 IShellFolder::CreateViewObject ,並將 riid 設定為 IID_IShellView 來要求資料夾檢視物件。 建立資料夾檢視的程式如下:
- 您的資料夾物件會建立資料夾檢視物件的新實例,並傳回其 IShellView 介面的指標。
- Windows 檔案總管會呼叫 IShellView::CreateViewWindow 方法,初始化資料夾檢視物件。 建立資料夾檢視視窗的子視窗,並將其控制碼傳回給 Windows 檔案總管。
- 資料夾檢視物件使用 Windows 檔案總管IShellBrowser 介面來自訂 Windows 檔案總管工具列、功能表列和狀態列。
- 資料夾檢視物件會顯示子視窗中資料夾的內容。
- 資料夾檢視物件會處理使用者與資料夾檢視和任何資料夾特定工具列或功能表列專案的互動。
初始化資料夾檢視物件
Windows 檔案總管會呼叫 IShellView::CreateViewWindow 方法,初始化資料夾檢視物件。 方法的參數會提供資料夾檢視物件,並提供建立子視窗所需的資訊,以用來顯示資料夾的內容:
- 上一個資料夾檢視物件的 IShellView 介面指標。 此參數可以設定為 Null。
- FOLDERSETTINGS結構,其中包含上一個資料夾檢視的設定。
- Windows 檔案總管IShellBrowser 介面的指標。
- 具有資料夾檢視視窗維度的 RECT 結構。
在終結先前的資料夾檢視物件之前,會呼叫 IShellView::CreateViewWindow 方法。 因此 ,IShellView 介面指標可讓您與先前的資料夾檢視物件通訊。 如果上一個資料夾屬於您的延伸模組,而且使用相同的顯示配置,這個介面主要很有用。 若是如此,您可以與先前的資料夾檢視物件通訊,以便交換私用設定。
判斷 IShellView 指標是否屬於延伸模組的簡單方式,就是讓所有資料夾檢視物件公開私人介面。 呼叫 IShellView::QueryInterface 以要求私人介面,並檢查傳回值,以判斷資料夾檢視物件是否為其中一個。 接著,您可以在該介面上使用私用方法來交換資訊。
FOLDERSETTINGS結構包含上一個資料夾檢視的顯示設定。 主要設定是檢視模式:大型圖示、小型圖示、清單或詳細資料。 另外還有一個旗標,其中包含各種顯示選項的設定,例如是否應該靠左對齊檢視。 您的資料夾顯示應遵循這些設定,盡可能為使用者提供從某個資料夾到另一個資料夾的一致體驗。 您應該儲存此結構,並在設定變更時加以更新。 Windows 檔案總管會呼叫 IShellView::GetCurrentInfo ,以取得此結構的最新值,然後再開啟下一個資料夾檢視。
IShellBrowser介面是由 Windows 檔案總管公開。 這個介面是 IShellView 的隨附介面,可讓資料夾檢視物件與 Windows 檔案總管通訊。 沒有其他方式可以擷取這個介面指標,因此您的資料夾檢視物件應該儲存它以供稍後使用。 特別是,您必須呼叫 IShellBrowser::GetWindow ,以擷取您將用來建立子視窗的父資料夾檢視視窗。 請注意,IShellBrowser::GetWindow 方法不會包含在 IShellBrowser 檔中,因為它繼承自 IOleWindow。 儲存介面指標之後,請記得呼叫 IShellBrowser::AddRef 以遞增介面的參考計數。 當您不再需要 介面時,請呼叫 IShellBrowser::Release。
若要建立子視窗:
- 檢查 FOLDERSETTINGS 和 RECT 結構。
- 如有需要,請從上一個資料夾檢視物件取得私人設定。
- 呼叫 IShellBrowser::GetWindow 以擷取父資料夾檢視視窗。
- 建立在上一個步驟中取得的資料夾檢視視窗子系,並將它傳回 Windows 檔案總管。
顯示資料夾檢視
建立子視窗並傳回 Windows 檔案總管之後,您就可以顯示資料夾的內容。 一般而言,延伸模組會藉由讓子視窗主控 清單檢視控制項 或 WebBrowser 控制項來顯示其資訊。 清單檢視控制項可讓您複寫 Windows 檔案總管 傳統檢視。 WebBrowser 控制項可讓您使用動態 HTML (DHTML) 檔來顯示資訊,就像 Windows 檔案總管網頁檢視一樣。 如需詳細資訊,請參閱這些控制項的檔。
資料夾檢視視窗一律存在,即使沒有焦點也一樣。 因此,您應該維護子視窗的三種狀態:
- 以焦點啟動。 資料夾檢視已建立並具有焦點。 設定適合焦點狀態的功能表列或工具列專案。
- 啟動但沒有焦點。 資料夾檢視已建立且作用中,但沒有焦點。 設定適合非焦點狀態的功能表列或工具列專案。 省略套用至資料夾檢視內專案選取範圍的任何專案。
- 關閉。 資料夾檢視即將終結。 移除所有資料夾特定的功能表項目。
Windows 檔案總管會呼叫 IShellView::UIActivate,在視窗狀態變更時通知您的資料夾檢視物件。 接著,當使用者呼叫 IShellBrowser::OnViewWindowActive來開機檔案夾檢視視窗時,資料夾檢視物件應該會通知 Windows 檔案總管。 如需此介面的進一步討論,請參閱 使用 IShellBrowser 與 Windows 檔案總管通訊。
當資料夾檢視為使用中時,您需要處理屬於子視窗的任何 Windows 訊息,例如 WM_SIZE。 您的視窗程式也會收到您新增至 Windows 檔案總管功能表列或工具列之任何專案的 WM_COMMAND 訊息。
建立資料夾檢視之後,Windows 檔案總管會呼叫資料夾檢視物件的 IShellView 介面,以傳遞各種資訊。 您的物件必須據以修改其顯示。 當資料夾檢視即將終結時,Windows 檔案總管會呼叫其 IShellView::D estroyViewWindow 方法,通知資料夾檢視物件。
實作 IShellView
建立資料夾物件之後,Windows 檔案總管會呼叫各種 IShellView 方法來要求資訊,或通知物件 Windows 檔案總管狀態的變更。 本節概述如何實作這些 IShellView 方法。 其餘方法會用於更特製化的目的,例如 [檔案開啟一般] 對話方塊。 如需詳細資訊,請參閱 IShellView 檔。
AddPropertySheetPages
當使用者從 [Windows 檔案總管工具] 功能表中選取 [資料夾選項] 時,會顯示內容表,讓使用者修改資料夾選項。 Windows 檔案總管會呼叫資料夾檢視物件的 IShellView::AddPropertySheetPages 方法,讓您將頁面新增至此屬性工作表。
Windows 檔案總管會在IShellView::AddPropertySheetPages的lpfn參數中傳遞AddPropSheetPageProc回呼函式的指標。 呼叫 CreatePropertySheetPage 以建立頁面,然後呼叫 AddPropSheetPageProc 將其新增至屬性工作表。 如需如何處理屬性工作表的進一步討論,請參閱 屬性工作表。
GetCurrentInfo
當使用者從某個資料夾切換到另一個資料夾時,Windows 檔案總管會嘗試維護類似的資料夾檢視。 例如,如果上一個資料夾檢視顯示大型圖示,則也應該顯示下一個圖示。 當 Windows 檔案總管呼叫 IShellView::CreateViewWindow 來初始化資料夾檢視物件時,此方法會收到 FOLDERSETTINGS 結構。 此結構包含可讓您讓資料夾檢視與上一個資料夾檢視一致的資訊。
若要協助確保下一個檢視與目前檢視一致,請儲存 FOLDERSETTINGS 結構。 如果檢視變更,例如從大型圖示變更為小型圖示,請據以更新結構。 在切換檢視之前,Windows 檔案總管會呼叫 IShellView::GetCurrentInfo ,要求目前的 FOLDERSETTINGS 值將它們傳遞至下一個資料夾檢視物件。
重新整理
使用者可以從 [檢視] 功能表選取 [重新整理] 或按 F5 鍵,確保資料夾檢視反映資料夾的目前狀態。 當使用者這麼做時,Windows 檔案總管會呼叫 IShellView::Refresh 方法。 您的資料夾檢視物件應該會立即更新資料夾檢視顯示。
SaveViewState
Windows 檔案總管會呼叫 IShellView::SaveViewState 方法來提示資料夾檢視物件儲存其檢視狀態。 接著,您可以在下次檢視資料夾時復原狀態。 儲存檢視狀態的慣用方式是呼叫 IShellBrowser::GetViewStateStream 方法。 這個方法會傳回 IStream 介面,您的資料夾檢視物件可用來儲存其狀態。 當您建立另一個資料夾檢視時,您可以呼叫相同的 IShellBrowser::GetViewStateStream 方法來取得 IStream 指標,讓您讀取先前資料夾檢視所儲存的設定。
TranslateAcelerator
當使用者按下快速鍵時,Windows 檔案總管會呼叫 IShellView::TranslateAccelerator,將訊息傳遞至資料夾檢視物件。 傳回S_FALSE,讓 Windows 檔案總管處理訊息。 如果您的資料夾檢視物件已處理郵件,請傳回S_OK。
當資料夾檢視視窗有焦點時,Windows 檔案總管會在處理訊息之前呼叫 IShellView::TranslateAccelerator 。 由於大部分訊息通常與 Windows 檔案總管功能表列或工具列命令相關聯,所以您的資料夾檢視物件通常應該會傳回S_FALSE。 Windows 檔案總管接著可以正常處理訊息。 只有在郵件是資料夾特定的,而且您不想讓 Windows 檔案總管執行任何進一步的處理時,才會傳回S_OK。 如果資料夾檢視沒有焦點,Windows 檔案總管會先處理訊息。 它只會在未處理訊息時呼叫 IShellBrowser::TranslateAcceleratorSB 。
使用 IShellBrowser 與 Windows 檔案總管通訊
資料夾檢視物件會使用 IShellBrowser 介面與 Windows 檔案總管通訊,以用於各種用途,包括:
修改 Windows 檔案總管功能表列
Windows 檔案總管功能表列可讓使用者啟動各種命令。 根據預設,功能表列僅支援 Windows 檔案總管特定的命令。 Windows 檔案總管會處理相關的 WM_COMMAND 訊息,而且不會傳遞至資料夾檢視物件。 不過,您可以修改功能表列,以使用 IShellBrowser包含一或多個資料夾特定的功能表項目。 Windows 檔案總管會將這些專案的相關聯WM_COMMAND訊息傳遞至資料夾物件的視窗程式進行處理。 您也可以移除或停用任何不適用於您應用程式的標準命令。
資料夾檢視物件通常會在第一次顯示資料夾檢視之前修改功能表列。 當資料夾檢視損毀時,它們必須將功能表列傳回其原始狀態。 當您的資料夾檢視取得或失去焦點時,您可能也需要修改功能表列。
因為 Windows 檔案總管會在每次資料夾檢視視窗的狀態變更時呼叫 IShellView::UIActivate ,所以功能表列修改通常會包含在該方法的實作中。 修改 Windows 檔案總管功能表列的基本程式如下:
- 呼叫 CreateMenu 以建立功能表控制碼。
- 呼叫 IShellBrowser::InsertMenusSB,將該功能表控制碼傳遞至 Windows 檔案總管。 Windows 檔案總管會填入其功能表資訊。
- 視需要修改功能表。
- 呼叫 IShellBrowser::SetMenuSB 讓 Windows 檔案總管顯示修改過的功能表列。
Windows 檔案總管在其功能表列上有六個快顯功能表。 如同所有 OLE 容器,Windows 檔案總管功能表分成六個群組:檔案、編輯、容器、物件、視窗和說明。 下表列出 Windows 檔案總管快顯功能表及其相關聯的群組,以及功能表識別碼。
快顯功能表 | 識別碼 | 群組 |
---|---|---|
檔案 | FCIDM_MENU_FILE | 檔案 |
編輯 | FCIDM_MENU_EDIT | 檔案 |
檢視 | FCIDM_MENU_VIEW | 容器 |
我的最愛 | FCIDM_MENU_FAVORITES | 容器 |
工具 | FCIDM_MENU_TOOLS | 容器 |
說明 | FCIDM_MENU_HELP | 時間範圍 |
當您藉由呼叫 IShellBrowser::InsertMenusSB將功能表控制碼傳遞至 Windows 檔案總管時,也必須將指標傳遞給成員已初始化為零的 OLEMENUGROUPWIDTHS 結構。
當 IShellBrowser::InsertMenusSB傳回時,Windows 檔案總管會新增其功能表項目。 然後,您可以使用傳回的功能表控制碼搭配標準 Windows 功能表函式,例如 InsertMenuItem 來:
- 將專案新增至 Windows 檔案總管快顯功能表。
- 修改或刪除 Windows 檔案總管快顯功能表中的現有專案。
- 新增快顯功能表。
使用表格中列出的識別碼來識別各種 Windows 檔案總管快顯功能表。
注意
若要避免與 Windows 檔案總管命令識別碼發生衝突,您新增的任何功能表項目識別碼必須落在FCIDM_SHVIEWFIRST和FCIDM_SHVIEWLAST之間。 這兩個值是在 Shlobj.h 中定義。
一旦您完成功能表的修改,請呼叫 IShellBrowser::SetMenuSB 讓 Windows 檔案總管顯示新的功能表列。
一開始顯示資料夾檢視之後,Windows 檔案總管會在每次資料夾檢視取得或失去焦點時呼叫 IShellView::UIActivate 。 如果您有任何與資料夾檢視狀態敏感的功能表項目,則每次狀態變更時,都應該據以修改功能表。 例如,您可能有一個功能表項目,其作用於使用者已選取的資料夾檢視中的專案。 當資料夾檢視失去焦點時,您應該停用或移除此功能表項目。
當 Windows 檔案總管呼叫 IShellView::UIActivate 以指出資料夾檢視已停用時,請呼叫 IShellBrowser::RemoveMenusSB,將功能表列還原為其原始狀態。
修改 Windows 檔案總管工具列
除了修改 Windows 檔案總管功能表列之外,您也可以將按鈕新增至工具列。 如同功能表列,工具列修改通常是 IShellView::UIActivate 實作 的一部分。 將按鈕新增至 Windows 檔案總管工具列的程式如下:
- 將按鈕的點陣圖新增至工具列的影像清單。
- 定義按鈕的文字字串。
- 將按鈕新增至工具列。
若要將點陣圖新增至工具列的影像清單,請呼叫IShellBrowser::SendControlMsg,將TB_ADDBITMAP訊息傳送至工具列。 若要指定工具列控制項,請將方法的 id 參數設定為 FCW_TOOLBAR。 將 wParam 設定為點陣圖中的按鈕影像數目,並將 lParam 設定為 TBADDBITMAP 結構的位址。 影像索引會在 pret 參數中傳回。
有兩種方式可以定義按鈕的字串:
- 將字串指派給按鈕TBBUTTON結構的iString成員。
- 呼叫 IShellBrowser::SendControlMsg 以傳送工具列控制項 TB_ADDSTRING 訊息。 wParam參數應設定為零,並將lParam參數設定為字串。 字串索引會在 pret 參數中傳回。
若要將按鈕新增至工具列,請填入 TBBUTTON 結構,並將它傳遞至 IShellBrowser::SetToolbarItems。 如同功能表,您的命令識別碼必須落在FCIDM_SHVIEWFIRST與FCIDM_SHVIEWLAST之間。 工具列接著會將按鈕附加至現有按鈕的右邊。
例如,下列程式碼片段會將一個標準按鈕新增至 Windows 檔案總管工具列,其命令識別碼為 IDB_MYBUTTON。
TBADDBITMAP tbadbm;
int iButtonIndex;
TBBUTTON tbb;
tbadbm.hInst = g_hInstance; // The module's instance handle
tbadbm.nID = IDB_BUTTONIMAGE; // The bitmap's resource ID
psb->SendControlMsg(FCW_TOOLBAR, TB_ADDBITMAP, 1,
reinterpret_cast<LPARAM>(&tbadbm), &iButtonIndex);
psb->SendControlMsg(FCW_TOOLBAR, TB_ADDSTRING, NULL,
reinterpret_cast<LPARAM>(szLabel), &iStringIndex);
ZeroMemory(&tbb, sizeof(TBBUTTON));
tbb.iBitmap = iButtonIndex;
tbb.iCommand = IDB_MYBUTTON;
tbb.iString = iStringIndex;
tbb.fsState = TBSTATE_ENABLED;
tbb.fsStyle = TBSTYLE_BUTTON;
psb->SetToolbarItems(&tbb, 1, FCT_MERGE);
如需如何處理工具列控制項的進一步討論,請參閱 工具列控制項。
修改 Windows 檔案總管狀態列
您可以使用 Windows 檔案總管狀態列來顯示各種有用的資訊。 有兩種方式可以使用狀態列:
- 使用 IShellBrowser::SetStatusTextSB 在狀態列上顯示文字字串。
- 使用 IShellBrowser::SendControlMsg將訊息直接傳送至狀態列控制項。
第一個方法很簡單,但足以用於許多用途。 若要有更大的彈性,您可以呼叫 IShellBrowser::SendControlMsg 並將 id 參數設定為 FCW_STATUS,直接將訊息傳送至狀態列控制項。 如需狀態列控制項的進一步討論,請參閱 狀態列。
儲存檢視特定資訊
當檢視即將終結時,儲存檢視的狀態或設定等資訊通常很有用。 Windows 檔案總管會呼叫 IShellView::SaveViewState,提示您執行這項工作。 儲存檢視特定資訊的慣用方式是呼叫 IShellBrowser::GetViewStateStream。 這個方法提供 IStream 介面,可用來儲存資訊。 您可以使用任何適當的資料格式。