使用 Windows 檔案總管進行開發
Windows 檔案總管是功能強大的資源流覽和管理應用程式。 Windows 檔案總管可以透過Explorer.exe或 IExplorerBrowser 介面來存取為整合式整體。 Windows 檔案總管 (Explorer.exe) 可以使用 ShellExecuteEx 或類似的函式,以個別進程的形式繁衍。
您可以使用 IShellWindows (CLSID_ShellWindows) 來探索和程式設計開啟總管視窗,而可以使用 IWebBrowser2 (CLSID_ShellBrowserWindow) 來建立 Windows 檔案總管的新實例。
下列程式碼範例示範如何使用 Windows 檔案總管自動化模型來建立及探索執行中的總管視窗。
#define _WIN32_WINNT 0x0600
#define _WIN32_IE 0x0700
#define _UNICODE
#include <windows.h>
#include <shobjidl.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <propvarutil.h>
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "propsys.lib")
// Use the Shell Windows object to find all of the explorer and IExplorer
// windows and close them.
void CloseExplorerWindows()
{
IShellWindows* psw;
if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows,
NULL,
CLSCTX_LOCAL_SERVER,
IID_PPV_ARGS(&psw))))
{
VARIANT v = { VT_I4 };
if (SUCCEEDED(psw->get_Count(&v.lVal)))
{
// Walk backward to make sure that the windows that close
// do not cause the array to be reordered.
while (--v.lVal >= 0)
{
IDispatch *pdisp;
if (S_OK == psw->Item(v, &pdisp))
{
IWebBrowser2 *pwb;
if (SUCCEEDED(pdisp->QueryInterface(IID_PPV_ARGS(&pwb))))
{
pwb->Quit();
pwb->Release();
}
pdisp->Release();
}
}
}
psw->Release();
}
}
// Convert an IShellItem or IDataObject into a VARIANT that holds an IDList
// suitable for use with IWebBrowser2::Navigate2.
HRESULT InitVariantFromObject(IUnknown *punk, VARIANT *pvar)
{
VariantInit(pvar);
PIDLIST_ABSOLUTE pidl;
HRESULT hr = SHGetIDListFromObject(punk, &pidl);
if (SUCCEEDED(hr))
{
hr = InitVariantFromBuffer(pidl, ILGetSize(pidl), pvar);
CoTaskMemFree(pidl);
}
return hr;
}
HRESULT ParseItemAsVariant(PCWSTR pszItem, IBindCtx *pbc, VARIANT *pvar)
{
VariantInit(pvar);
IShellItem *psi;
HRESULT hr = SHCreateItemFromParsingName(pszItem, NULL, IID_PPV_ARGS(&psi));
if (SUCCEEDED(hr))
{
hr = InitVariantFromObject(psi, pvar);
psi->Release();
}
return hr;
}
HRESULT GetKnownFolderAsVariant(REFKNOWNFOLDERID kfid, VARIANT *pvar)
{
VariantInit(pvar);
PIDLIST_ABSOLUTE pidl;
HRESULT hr = SHGetKnownFolderIDList(kfid, 0, NULL, &pidl);
if (SUCCEEDED(hr))
{
hr = InitVariantFromBuffer(pidl, ILGetSize(pidl), pvar);
CoTaskMemFree(pidl);
}
return hr;
}
HRESULT GetShellItemFromCommandLine(REFIID riid, void **ppv)
{
*ppv = NULL;
HRESULT hr = E_FAIL;
int cArgs;
PWSTR *ppszCmd = CommandLineToArgvW(GetCommandLineW(), &cArgs);
if (ppszCmd && cArgs > 1)
{
WCHAR szSpec[MAX_PATH];
StringCchCopyW(szSpec, ARRAYSIZE(szSpec), ppszCmd[1]);
PathUnquoteSpacesW(szSpec);
hr = szSpec[0] ? S_OK : E_FAIL; // Protect against empty data
if (SUCCEEDED(hr))
{
hr = SHCreateItemFromParsingName(szSpec, NULL, riid, ppv);
if (FAILED(hr))
{
WCHAR szFolder[MAX_PATH];
GetCurrentDirectoryW(ARRAYSIZE(szFolder), szFolder);
hr = PathAppendW(szFolder, szSpec) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
hr = SHCreateItemFromParsingName(szFolder, NULL, riid, ppv);
}
}
}
}
return hr;
}
HRESULT GetShellItemFromCommandLineAsVariant(VARIANT *pvar)
{
VariantInit(pvar);
IShellItem *psi;
HRESULT hr = GetShellItemFromCommandLine(IID_PPV_ARGS(&psi));
if (SUCCEEDED(hr))
{
hr = InitVariantFromObject(psi, pvar);
psi->Release();
}
return hr;
}
void OpenWindow()
{
IWebBrowser2 *pwb;
HRESULT hr = CoCreateInstance(CLSID_ShellBrowserWindow,
NULL,
CLSCTX_LOCAL_SERVER,
IID_PPV_ARGS(&pwb));
if (SUCCEEDED(hr))
{
CoAllowSetForegroundWindow(pwb, 0);
pwb->put_Left(100);
pwb->put_Top(100);
pwb->put_Height(600);
pwb->put_Width(800);
VARIANT varTarget = {0};
hr = GetShellItemFromCommandLineAsVariant(&varTarget);
if (FAILED(hr))
{
hr = GetKnownFolderAsVariant(FOLDERID_UsersFiles, &varTarget);
}
if (SUCCEEDED(hr))
{
VARIANT vEmpty = {0};
hr = pwb->Navigate2(&varTarget, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
if (SUCCEEDED(hr))
{
pwb->put_Visible(VARIANT_TRUE);
}
VariantClear(&varTarget);
}
pwb->Release();
}
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
CloseExplorerWindows();
OpenWindow();
CoUninitialize();
}
return 0;
}
您可以使用 IExplorerBrowser 介面來裝載 Windows 檔案總管工作區。 Windows 檔案總管用戶端和命名空間樹狀結構控制項是 Windows Vista 和更新版本的標準元件。 開發人員可以將介面重複使用為建置元件。 這些控制項的其中一個常見用法是建立適合問題網域的自訂總管。
Windows 檔案總管中的控制項會分類為下列功能類別:
流覽控制項可協助使用者判斷內容,並流覽相關聯的邏輯網域空間,稱為 pagespace。 例如,Windows 檔案總管的頁面空間是 Shell 命名空間。 分頁空間是由零或多個頁面所組成。
下表列出並描述 Windows Vista 和更新版本作業系統中 Windows 檔案總管中可用的導覽控制項。
導覽控制項 | 描述 |
---|---|
位址列 (階層連結控制項) | 顯示頁面空間中目前頁面的位址。 您可以按一下階層連結按鈕,以流覽至頁面空間中的任何上階。 使用者也可以輸入要流覽的 URL 和路徑。 |
資料夾樹狀結構 | 提供新的樹狀結構控制項版本,針對大型分頁空間進行優化。 |
出差 | 透過網頁樣式按鈕啟用相對流覽,例如[上一頁] 和 [向前]。 |
標題 | 顯示目前的總管名稱和內容。 |
Pagespace | 顯示頁面空間的目前分支。 頁面可以依不同的準則排序。 使用者可以按一下頁面以流覽至該頁面。 |
命令控制項會將 Windows 檔案總管的功能公告給使用者。 這些控制項會執行一般動作或一個所選項目的特定動作。
命令控制項 | 描述 |
---|---|
工具列 | 顯示常用命令的按鈕, (新版的命令工具列) 。 自訂選項包括下拉式按鈕、分割按鈕、選擇性描述性文字和溢位區域。 |
主圖 | 顯示為工具列中央的單一選擇性自訂控制項。 它代表目前內容的主要命令。 |
功能表列 | 透過功能表呈現命令。 |
操作功能表 | 列出可用命令的內容相關子集,這些命令會在專案上按一下滑鼠右鍵時顯示。 |
屬性和預覽控制項可用來預覽專案,以及檢視和編輯專案屬性。
控制 | 描述 |
---|---|
預覽 | 顯示所選項目的預覽,例如縮圖或即時圖示。 |
屬性 | 顯示所選項目的屬性。 針對多個選取專案,它會顯示所選項目群組的屬性摘要。 針對 Null 選取範圍,它會顯示目前頁面的屬性摘要, (listview) 的內容。 |
篩選和檢視控制項可用來操作 listview 中的專案集,以及變更 listview 中專案的呈現方式。
控制 | 描述 |
---|---|
Filter | 根據列為資料行的屬性,篩選或排列 listview 中的專案。 按一下資料行會依該屬性排序。 |
Wordwheel | 根據輸入文字字串,以動態方式和累加方式篩選 listview 中顯示的專案。 |
檢視 | 可讓使用者變更 listview 控制項的檢視模式。 滑杆可用來判斷圖示大小。 |
listview 控制項可用來檢視四種檢視模式之一中的一組專案:詳細資料、磚、圖示或 panorama。 listview 控制項也可讓使用者選取並啟用一或多個專案。
警告
雖然其中有些控制項的名稱和/或功能類似于 System.Windows.Controls 命名空間中找到的標準Windows Presentation Foundation (WPF) 控制項,但它們是不同的類別。
這些個別控制項主要是透過使用者互動或控制項本身所產生的事件,共同運作。 下表顯示三個主要事件類別。
事件類別目錄 | 範例 |
---|---|
導覽 | 從一個頁面移至另一個頁面。 |
選取項目 | 變更 listview 中的目前選取範圍。 |
檢視變更 | 變更 listview 中的簡報順序或檢視模式。 |