Как я могу использовать вид папки по умолчанию в расширении пространства имен оболочки? - PullRequest
0 голосов
/ 27 ноября 2011

Я изучал, как реализовать расширение пространства имен.

В NSE должны отображаться файлы и папки (это физические файлы и папки , но , расположенные в другом месте на диске ).

Кроме того, NSE должен вести себя как можно ближе к обычному представлению Explorer , например. должно иметь:

  • Контекстные меню, которые обычно отображаются в обычном представлении проводника, которые применимы к выбранным файлам / папкам
  • Перетаскивание (как файлов / папок, так и других вещей, таких как обрывки документов)
  • «Перетаскивание вправо» (например, 7Zips «Извлечь здесь ...»)
  • Буфер обмена Копировать / Вырезать / Вставить
  • Поделиться с записями
  • Должны работать любые зарегистрированные обработчики оверлея Icon Shell (например, Tortoise SVN / GIT)
  • Размер колонки / повторный заказ
  • Просмотр настроек, включая порядок и группировку

Итак, все, что может сделать представление Explorer, мы должны.

Глядя на все то, что Explorer может делать (что я привык считать само собой разумеющимся) , я чувствовал себя немного ошеломленным.

Поскольку я ленивый и реалист (я понимаю, что практически невозможно воспроизвести всю эту функциональность без проблем), я планирую повторно использовать функциональность представления Explorer в моем NSE .

Я смотрел на различные образцы NSE. Большинство из них используют виртуальные данные, но, как я уже сказал, я представляю физические файлы и папки в другом месте на диске. Я также читал о методе SHCreateShellFolderView.

Вооружившись этой информацией, я подумал, что это будет относительно простой случай предоставления PIDL моей корневой папки, а затем в моем IShellFolder::CreateViewObject вызове SHCreateShellFolder метода. Вот этот метод:

STDMETHODIMP CShellFolderImpl::CreateViewObject( 
    HWND hwndOwner, 
    REFIID riid, 
    void** ppvOut )
{
    HRESULT hr=E_NOINTERFACE;

    if ( NULL == ppvOut )
        return E_POINTER;

    *ppvOut = NULL;

    if (riid == IID_IShellView)
    {
        SFV_CREATE SfvCreate = 
        {
            sizeof(SFV_CREATE) 
        };


        if (SUCCEEDED(hr = QueryInterface(IID_PPV_ARGS(&SfvCreate.pshf))))
        {
            hr = ::SHCreateShellFolderView(
                &SfvCreate, 
                reinterpret_cast<IShellView **>(ppvOut));
        }

        SfvCreate.pshf->Release();
    }
    else if (riid == IID_ITransferSource)
    {

    }

    return hr;
}

Нет такой удачи с этим. SHCreateShellFolderView всегда возвращался E_NOTIMPL. Оказывается, это потому, что для этого требуется указатель на что-то, реализующее IShellFolder2IPersist2 для GetCurFolder, где я могу предоставить свой PIDL). Моя папка только что реализована IShellFolder и IPerist.

Итак, изменив их для реализации новых интерфейсов, я получил ... ничего! NSE будет загружен Explorer, будет вызван конструктор, но сразу после этого будет вызван деструктор. Если я изменил интерфейсы обратно на те, что были, он загорелся (но все равно с той же проблемой).

С тех пор я искал образец, который реализует IShellFolder2, но, опять же, документация такая же плохая, как и для остальных этих API.

Как я могу использовать SHCreateShellFolderView, чтобы мне не пришлось переопределять все, что уже делает Explorer?

1 Ответ

2 голосов
/ 02 декабря 2011

Даже если вы можете использовать и встраивать окно проводника Windows для расширения своего пространства имен, проблема заключается в том, что вы больше не контролируете его действия.Например, если пользователь дважды щелкает папку, будет просматриваться фактическая папка файловой системы, а не ваш узел расширения пространства имен, представляющий папку файловой системы.

Ваш единственный вариант - выполнить собственную реализацию.Посмотрите EZNamespaceExtensionsMFC , который позволяет очень легко разрабатывать расширения пространства имен.У него есть пример «FileSystemBrowser», который можно использовать в качестве отправной точки.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я работаю в LogicNP, разработчиках EZNamespaceExtensionsMFC.

...