Ich habe recherchiert, wie man eine Namespace Extension implementiert.
Die NSE sollte Dateien und Ordner anzeigen (sie sind physische Dateien und Ordner aber die sich an anderer Stelle auf der Festplatte befinden ).
Außerdem muss die NSE sich so nah wie möglich an die normale Explorer-Ansicht halten z.B. muss es haben:
- Kontextmenüs, die normalerweise in einer normalen Explorer-Ansicht erscheinen würden und die für die ausgewählte(n) Datei/Ordner gelten
- Ziehen und Ablegen (sowohl von Dateien/Ordnern als auch von anderen Dingen wie Document Scraps)
- Ziehen und Ablegen mit der rechten Maustaste (z. B. 7Zips "Hier extrahieren...")
- Zwischenablage Kopieren/Ausschneiden/Einfügen
- Teilen mit Einträgen
- Jeder registrierte Shell Icon Overlay Handler muss funktionieren (z.B. Tortoise SVN/GIT)
- Spaltenanpassung/Neubestellung
- Individuelle Anpassung der Ansicht, einschließlich Anordnung und Gruppierung
Alles, was die Explorer-Ansicht kann, müssen wir auch tun.
Alle Möglichkeiten, die der Explorer bietet (die ich früher für selbstverständlich hielt) fühlte ich mich ein wenig überfordert.
Da ich sowohl faul als auch realistisch bin (mir ist klar, dass es nahezu unmöglich wäre, all diese Funktionen ohne Probleme zu replizieren), ist mein Plan die Funktionalität der Explorer-Ansicht in meinem NSE wiederverwenden .
Ich habe mir verschiedene Beispiele für NSEs angeschaut. Die meisten von ihnen verwenden virtuelle Daten, aber wie ich schon sagte, stelle ich physische Dateien und Ordner an anderer Stelle auf der Festplatte dar. Ich habe auch gelesen, dass die SHCreateShellFolderView
Methode.
Mit diesen Informationen ausgestattet, dachte ich, dass es relativ einfach sein würde, eine PIDL
meines Root-Ordners und dann in meinem IShellFolder::CreateViewObject
aufrufen SHCreateShellFolder
Methode. Hier ist diese Methode:
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;
}
Damit hatte ich kein Glück. SHCreateShellFolderView
immer wieder zurückkehrte E_NOTIMPL
. Es stellt sich heraus, dass dies daran liegt, dass ein Zeiger auf etwas benötigt wird, das IShellFolder2
(und IPersist2
für GetCurFolder
wo ich meine Dienste anbieten kann PIDL
). Mein Ordner hat gerade IShellFolder
y IPerist
.
Nachdem ich diese also geändert hatte, um die neueren Schnittstellen zu implementieren, bekam ich... nichts! Die NSE wurde vom Explorer geladen, der Konstruktor wurde aufgerufen, aber unmittelbar danach wurde der Destruktor aufgerufen. Wenn ich die Schnittstellen wieder so änderte, wie sie waren, funktionierte es (aber immer noch mit demselben Problem).
Seitdem habe ich nach einem Beispiel, das Folgendes implementiert IShellFolder2
aber auch hier ist die Dokumentation genauso schlecht wie bei den anderen APIs.
Wie kann ich die SHCreateShellFolderView
damit ich nicht alles neu implementieren muss, was der Explorer bereits tut?