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

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

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

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

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

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

Глядя на все, что может делать 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 будет загружен проводником, будет вызван конструктор, но сразу после этого будет вызван деструктор. Если я изменил интерфейсы обратно на прежние, он загорелся (но все еще с той же проблемой).

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

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


person Steve Dunn    schedule 27.11.2011    source источник


Ответы (1)


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

Ваш единственный вариант - сделать свою собственную реализацию. Ознакомьтесь с EZNamespaceExtensionsMFC, который упрощает разработку расширений пространства имен. В нем есть образец FileSystemBrowser, который вы можете использовать в качестве отправной точки.

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

person logicnp    schedule 02.12.2011