Разработка с помощью обозревателя Windows

Обозреватель Windows — это мощное приложение для просмотра ресурсов и управления. Обозреватель Windows можно получить как интегрированное целое через Explorer.exe или интерфейс IExplorerBrowser. Обозреватель Windows (Explorer.exe) можно создать как отдельный процесс с помощью ShellExecuteEx или аналогичной функции.

Открытые окна обозревателя можно обнаружить и запрограммировать с помощью IShellWindows (CLSID_ShellWindows), а новые экземпляры Проводника Windows можно создавать с помощью IWebBrowser2 (CLSID_ShellBrowserWindow).

В следующем примере кода показано, как модель автоматизации Проводника 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;
}

Клиентская область обозревателя Windows может размещаться с помощью интерфейса IExplorerBrowser. Клиент Проводника Windows и элементы управления деревом пространства имен являются стандартными компонентами Windows Vista и более поздних версий. Разработчики могут повторно использовать интерфейсы в качестве стандартных компонентов. Одним из распространенных способов использования этих элементов управления является создание настраиваемых обозревателей, соответствующих домену проблемы.

Элементы управления в проводнике Windows классифицируются по следующим функциональным категориям:

Элементы управления навигацией помогают пользователям определить контекст и перейти к связанному логическому пространству домена, называемому пространством страниц. Например, пространство страниц для проводника Windows — это пространство имен оболочки. Пространства страниц состоят из нуля или нескольких страниц.

В следующей таблице перечислены и описаны элементы управления навигацией, доступные в проводнике Windows в Windows Vista и более поздних операционных системах.

Элемент управления навигацией Описание
Адресная строка (элемент управления Breadcrumb) Отображает адрес текущей страницы в пространстве страниц. Кнопки хлебных крошек можно щелкнуть, чтобы перейти к любому предку в структуре страницы. Пользователи также могут вводить URL-адреса и пути для перехода.
Дерево папок Предоставляет новую версию элемента управления деревом, оптимизированную для больших пространств страниц.
Путешествовать Включает относительную навигацию через кнопки веб-стиля, такие как Back и Forward.
Титул Отображает имя и контекст текущего обозревателя.
Пространство страниц Отображает текущую ветвь пространства страниц. Страницы можно упорядочить по разным критериям. Пользователи могут щелкнуть страницу, чтобы перейти к ней.

 

Управление командами

Элементы управления командами объявляют функции и функциональные возможности проводника Windows пользователям. Эти элементы управления выполняют общие действия или действия, относящиеся к одному выбранному элементу или элементам.

Управление командами Описание
Панель инструментов Отображает кнопки для часто используемых команд (новая версия панели инструментов команд). Параметры настройки включают выпадающие кнопки, кнопки с разделенными функциями, необязательный описательный текст и область, где скрывается избыточное содержимое.
Герой Отображается как единый, необязательный, пользовательский элемент управления в центре панели инструментов. Она представляет основную команду для текущего контекста.
Строка меню Предоставляет команды с помощью меню.
Контекстное меню Выводит контекстно релевантное подмножество доступных команд, отображаемых в результате щелчка правой кнопкой мыши элемента.

 

Элементы управления свойствами и предварительным просмотром

Элементы управления свойствами и предварительным просмотром используются для предварительного просмотра элементов, а также для просмотра и редактирования свойств элементов.

Контроль Описание
Предварительный просмотр Отображает предварительный просмотр выбранного элемента, например миниатюру или живой значок.
Свойства Отображает свойства выбранного элемента. Для нескольких выборов отображается сводка свойств для выбранной группы элементов. Для выбора null отображается сводка свойств текущей страницы (содержимое представления списка).

 

Фильтрация и просмотр элементов управления

Элементы управления фильтрацией и представлением используются для управления набором элементов в представлении списка и для изменения представления элементов в представлении списка.

Контроль Описание
Фильтр Фильтрует или упорядочивает элементы в представлении списка на основе свойств, перечисленных как столбцы. При щелчке на столбец выполняется сортировка по соответствующему свойству.
Словесное колесо Динамически и добавочно фильтрует отображаемые элементы в представлении списка на основе входной текстовой строки.
Вид Позволяет пользователю изменить режим представления элемента управления listview. Ползунок можно использовать для определения размера значка.

 

Элемент управления ListView

Элемент управления listview используется для просмотра набора элементов в одном из четырех режимов представления: сведения, плитки, значки или панорама. Элемент управления listview также позволяет пользователю выбирать и активировать один или несколько элементов.

Осторожность

Хотя некоторые из этих элементов управления имеют имена и функции, аналогичные стандартным элементам управления Windows Presentation Foundation (WPF), найденным в пространстве имен System.Windows.Controls, они являются отдельными классами.

 

Эти отдельные элементы управления работают в основном через события, созданные взаимодействием пользователя или самими элементами управления. В следующей таблице показаны три основные категории событий.

Категория событий Пример
Навигация Переход с одной страницы на другую.
Отбор Изменение текущего выбора в представлении списка.
Просмотр изменений Изменение порядка презентации или режима представления в представлении списка.