在您可以使用命名空間物件之前,您需要一種方法來識別它。 這表示取得項目識別碼列表(PIDL)的指標,或在檔案系統物件的情況下取得其路徑。 本節討論取得對象標識碼的兩種較簡單方式。
若要適用於任何資料夾的更強大的方式,請使用 IShellFolder 介面。 如需詳細資訊,請參閱 取得有關資料夾內容的資訊。
OpenFiles 對話框
若要讓使用者巡覽命名空間並選取資料夾,您的應用程式可以使用 IFileDialog 介面。 使用 FOS_PICKFOLDERS 旗標呼叫這個介面,會在「挑選資料夾」模式中啟動 開啟檔案 一般對話方塊。
針對 Windows Vista 和更新版本,這是挑選資料夾的建議方式。
SHBrowseForFolder 對話方塊
若要讓使用者流覽命名空間並選取資料夾,您的應用程式只需叫用shBrowseForFolder。 呼叫此函式會啟動具有UI的對話框,其運作方式類似 Open或SaveAs 一般對話框。
當使用者選取資料夾時,SHBrowseForFolder 會傳回資料夾的完整 PIDL 及其顯示名稱。 如果資料夾位於檔案系統中,應用程式可以呼叫 SHGetPathFromIDList,將 PIDL 轉換成路徑。 應用程式也可以藉由指定根資料夾來限制使用者可以選取的資料夾範圍。 只有命名空間中根目錄下方的資料夾才會出現。 下圖顯示 [SHBrowseForFolder] 對話框,根資料夾設定為 Program Files。
稍後會提供如何使用 SHBrowseForFolder 的簡單範例。
特殊資料夾和 CSIDL
系統會將許多常用的資料夾指定為特殊 。 這些資料夾具有妥善定義的用途,而且大部分都存在於所有系統上。 即使它們一開始不存在,仍會定義其名稱和位置,以便稍後新增它們。 特殊資料夾的集合包含系統的所有標準虛擬資料夾,例如印表機、我的文件和網路鄰里。 它也包含一些標準文件系統資料夾,例如 Program Files 和 System。
即使資料夾是所有系統的標準元件,其命名空間中的名稱和位置可能會有所不同。 例如,某些系統上的系統目錄為 C:\Winnt\System32,而其他系統則為 C:\Windows\System32。 過去,環境變數提供了一種方式來判斷任何特定系統上特殊資料夾的名稱和位置。 殼層現在提供更健全且更有彈性的方式來識別特殊資料夾,CSIDL。 您通常應該使用它們,而不是環境變數。
不論特定系統上的名稱或位置為何,CSIDL 都提供識別和尋找特殊資料夾的統一方式。 不同於環境變數,CSIDL 可以搭配虛擬資料夾和檔案系統資料夾使用。 每個特殊資料夾都有其專屬的唯一 CSIDL。 例如,Program Files 檔案系統資料夾的 CSIDL 為 CSIDL_PROGRAM_FILES,而 Network Neighborhood 虛擬資料夾的 CSIDL 為 CSIDL_NETWORK。
CSIDL 會與數個 Shell 函式的其中一個搭配使用,以擷取特殊資料夾的 PIDL 或特殊文件系統資料夾的路徑。 如果資料夾不存在於系統上,您的應用程式可以藉由結合其 CSIDL 與 CSIDL_FLAG_CREATE來強制建立它。 CSIDL 可以傳遞至下列函式:
- SHGetFolderLocation,它會擷取特殊資料夾的 PIDL。
- SHGetFolderPath,它會擷取檔系統特殊資料夾的路徑。
請注意,這兩個函式是使用Shell 5.0版引進的,並取代 SHGetSpecialFolderLocation 和 SHGetSpecialFolderPath 函式。
如何使用 CSIDL 和 SHBrowseForFolder 的簡單範例
下列範例函式 PidlBrowse 說明如何使用 CSIDL 來擷取資料夾的 PIDL,並使用 SHBrowseForFolder 讓用戶選取資料夾。 它會傳回所選取資料夾的 PIDL 和顯示名稱。
LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL, LPSTR pszDisplayName)
{
LPITEMIDLIST pidlRoot = NULL;
LPITEMIDLIST pidlSelected = NULL;
BROWSEINFO bi = {0};
if(nCSIDL)
{
SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);
}
else
{
pidlRoot = NULL;
}
bi.hwndOwner = hwnd;
bi.pidlRoot = pidlRoot;
bi.pszDisplayName = pszDisplayName;
bi.lpszTitle = "Choose a folder";
bi.ulFlags = 0;
bi.lpfn = NULL;
bi.lParam = 0;
pidlSelected = SHBrowseForFolder(&bi);
if(pidlRoot)
{
CoTaskMemFree(pidlRoot);
}
return pidlSelected;
}
呼叫的應用程式會傳入一個視窗控制碼,而SHBrowseForFolder需要此控制碼。 nCSIDL 參數是選擇性的 CSIDL,用來指定根資料夾。 只會顯示階層中根資料夾下方的資料夾。 稍早所示的圖例是呼叫此函式,並將 nCSIDL 設為 CSIDL_PROGRAM_FILES。 呼叫的應用程式也會傳入字串緩衝區,pszDisplayName,以在 PidlBrowse 傳回時保留所選取資料夾的顯示名稱。 呼叫應用程式的責任是使用 CoTaskMemFree來釋放 SHBrowseForFolder 所傳回的 IDList。