Abrufen von Informationen zum Inhalt eines Ordners

Im Abschnitt Abrufen der ID eines Ordners wurden zwei Ansätze zum Abrufen des Zeigers eines Namespace-Objekts auf eine Elementbezeichnerliste (PIDL) erläutert. Eine offensichtliche Frage ist: Sobald Sie eine PIDL haben, was können Sie damit tun? Eine damit verbundene Frage lautet: Was kann getan werden, wenn keiner der beiden Ansätze funktioniert oder für Ihre Anwendung geeignet ist? Um beide Fragen zu beantworten, muss man sich genauer ansehen, wie der Namespace implementiert ist. Der Schlüssel dazu ist die IShellFolder-Schnittstelle.

Verwenden der IShellFolder-Schnittstelle

Weiter oben in dieser Dokumentation wurden Namespace-Ordner als Objekte bezeichnet. Obwohl zu diesem Zeitpunkt der Begriff in einem lockeren Sinne verwendet wurde, ist es auch in einem strengen Sinne wahr. Jeder Namespace-Ordner wird durch ein COM-Objekt (Component Object Model) dargestellt. Jedes Ordnerobjekt macht eine Reihe von Schnittstellen verfügbar, die für eine Vielzahl von Aufgaben verwendet werden können. Einige Schnittstellen, die optional sind, werden möglicherweise nicht von allen Ordnern verfügbar gemacht. Alle Ordner müssen jedoch die grundlegende Schnittstelle, IShellFolder, bereitstellen.

Der erste Schritt bei der Verwendung eines Ordnerobjekts besteht darin, einen Zeiger auf die IShellFolder-Schnittstelle abzurufen. Zusätzlich zur Bereitstellung des Zugriffs auf die anderen Schnittstellen des Objekts macht IShellFolder eine Gruppe von Methoden verfügbar, die eine Reihe allgemeiner Aufgaben behandeln, von denen mehrere in diesem Abschnitt erläutert werden.

Um einen Zeiger auf die IShellFolder-Schnittstelle eines Namespace-Objekts abzurufen, müssen Sie zunächst SHGetDesktopFolder aufrufen. Diese Funktion gibt einen Zeiger auf die IShellFolder-Schnittstelle des Namespace-Stamms, d. h. des Desktops, zurück. Sobald Sie über die IShellFolder-Schnittstelle des Desktops verfügen, gibt es eine Vielzahl von Möglichkeiten, den Vorgang fortzusetzen.

Wenn Sie bereits über die PIDL des gewünschten Ordners verfügen, z. B. durch Aufrufen von SHGetFolderLocation, können Sie die IShellFolder-Schnittstelle abrufen, indem Sie die Methode IShellFolder::BindToObject des Desktops aufrufen. Wenn Sie den Pfad eines Dateisystemobjekts haben, müssen Sie zuerst seine PIDL erhalten, indem Sie die Methode IShellFolder::ParseDisplayName des Desktops aufrufen und dann IShellFolder::BindToObject aufrufen. Wenn keiner dieser Ansätze anwendbar ist, können Sie andere IShellFolder-Methoden verwenden, um im Namespace zu navigieren. Weitere Informationen finden Sie unter Navigieren im Namespace.

Auflisten der Inhalte eines Ordners

Das erste, was Sie normalerweise mit einem Ordner tun wollen, ist herauszufinden, was er enthält. Sie müssen zunächst die Methode IShellFolder::EnumObjects des Ordners aufrufen. Der Ordner erstellt ein standardmäßiges OLE-Aufzählungsobjekt und gibt dessen IEnumIDList-Schnittstelle zurück. Diese Schnittstelle stellt vier Standardmethoden (Klonen, Weiter, Zurücksetzen und Überspringen) zur Verfügung, die zum Auflisten der Inhalte des Ordners verwendet werden können.

Das grundlegende Verfahren zum Aufzählen des Inhalts eines Ordners lautet:

  1. Rufen Sie die Methode IShellFolder::EnumObjects für den Ordner auf, um einen Zeiger auf die IEnumIDList-Schnittstelle eines Enumerationsobjekts abzurufen.
  2. Übergeben Sie evtl. nicht zugewiesene PIDLs an IEnumIDList::Next. Weiter sorgt für die Zuweisung der PIDL, aber die Anwendung muss sie wieder freigeben, wenn sie nicht mehr benötigt wird. Wenn Weiter zurückgegeben wird, enthält die PIDL nur die Element-ID des Objekts und die endenden NULL-Zeichen. Anders ausgedrückt, handelt es sich um eine einstufige PIDL, relativ zum Ordner, und nicht um eine voll qualifizierte PIDL.
  3. Wiederholen Sie Schritt 2, bis Weiter S_FALSE zurückgibt, um anzugeben, dass alle Elemente aufgelistet wurden.
  4. Rufen Sie IEnumIDList::Release auf, um das Enumerationsobjekt freizugeben.

Hinweis

Es ist wichtig, nachzuverfolgen, ob Sie mit einer vollständigen oder relativen PIDL arbeiten. Einige Funktionen und Methoden akzeptieren beides, andere wiederum nur die eine oder die andere.

 

Die verbleibenden drei IEnumIDList-Methoden (Zurücksetzen, Überspringen und Klonen) sind nützlich, wenn Sie wiederholte Enumerationen des Ordners ausführen müssen. Sie ermöglichen es Ihnen, die Auflistung zurückzusetzen, ein oder mehrere Objekte zu überspringen und eine Kopie des Enumerationsobjekts zu erstellen, um den Zustand beizubehalten.

Bestimmen von Anzeigenamen und anderen Eigenschaften

Nachdem Sie alle PIDLs aufgelistet haben, die in einem Ordner enthalten sind, können Sie herausfinden, welche Art von Objekten sie darstellen. Die IShellFolder-Schnittstelle bietet eine Reihe nützlicher Methoden, von denen zwei hier erläutert werden. Weitere IShellFolder-Methoden und andere Shell-Ordnerschnittstellen werden später erläutert.

Eine der nützlichsten Eigenschaften ist der Anzeigename des Objekts. Um den Anzeigenamen eines Objekts abzurufen, übergeben Sie die PIDL an IShellFolder::GetDisplayNameOf. Obwohl sich das Objekt an einer beliebigen Stelle unterhalb des übergeordneten Ordners im Namespace befinden kann, muss die PIDL relativ zum Ordner sein.

IShellFolder::GetDisplayNameOf gibt den Anzeigenamen als Teil einer STRRET-Struktur zurück. Da das Extrahieren des Anzeigenamens aus einer STRRET-Struktur schwierig sein kann, stellt die Shell zwei Funktionen bereit, die den Auftrag für Sie ausführen, StrRetToStr und StrRetToBuf. Beide Funktionen verwenden eine STRRET-Struktur und geben den Anzeigenamen als normale Zeichenfolge zurück. Sie unterscheiden sich nur bei der Zuweisung der Zeichenfolge.

Neben dem Anzeigenamen kann ein Objekt eine Reihe von Attributen aufweisen, z. B. ob es sich um einen Ordner handelt oder ob es verschoben werden kann. Sie können die Attribute eines Objekts abrufen, indem Sie seine PIDL an IShellFolder::GetAttributesOf übergeben. Die vollständige Liste der Attribute ist ziemlich groß, daher sollten Sie die Referenzdatei für Details anzeigen. Beachten Sie, dass die PIDL, die Sie an GetAttributesOf übergeben, eine Ebene sein muss. Insbesondere akzeptiert IShellFolder::GetAttributesOf die PiDLs, die von IEnumIDList::Next zurückgegeben werden. Sie können ein Array von PIDLs übergeben, und GetAttributesOf gibt diese Attribute zurück, die alle Objekte im Array gemeinsam haben.

Wenn Sie über den vollqualifizierten Pfad oder die PIDL eines Objekts verfügen, bietet SHGetFileInfo eine einfache Möglichkeit, Informationen zu einem Objekt abzurufen, was für viele Zwecke ausreichend ist. SHGetFileInfo verwendet einen vollqualifizierten Pfad oder PIDL und gibt eine Vielzahl von Informationen über das Objekt zurück, einschließlich:

  • Der Anzeigename des Objekts
  • Die Attribute des Objekts
  • Ziehpunkte für die Symbole des Objekts
  • Ein Ziehpunkt zur Systemimageliste
  • Der Pfad der Datei, die das Objektsymbol enthält

Abrufen eines Zeigers auf die IShellFolder-Schnittstelle eines Unterordners

Sie können ermitteln, ob Ihr Ordner Unterordner enthält, indem Sie IShellFolder::GetAttributesOf aufrufen und überprüfen, ob das SFGAO_FOLDER Flag festgelegt ist. Wenn es sich bei einem Objekt um einen Ordner handelt, können Sie eine Bindung daran herstellen, wodurch Sie einen Zeiger auf die IShellFolder-Schnittstelle erhalten.

Rufen Sie zum Binden an einen Unterordner die Methode IShellFolder::BindToObject des übergeordneten Ordners auf. Diese Methode verwendet die PIDL des Unterordners und gibt einen Zeiger auf die IShellFolder-Schnittstelle zurück. Sobald Sie diesen Zeiger haben, können Sie die IShellFolder-Methoden verwenden, um den Inhalt der Unterordner aufzulisten, deren Eigenschaften zu bestimmen usw.

Bestimmen des übergeordneten Ordners eines Objekts

Wenn Sie über die PIDL eines Objekts verfügen, benötigen Sie möglicherweise einen Ziehpunkt zu einer der Schnittstellen, die vom übergeordneten Ordner verfügbar gemacht werden. Wenn Sie beispielsweise den Anzeigenamen ermitteln möchten, der einer PIDL mithilfe von IShellFolder::GetDisplayNameOfzugeordnet ist, müssen Sie zuerst die IShellFolder-Schnittstelle des übergeordneten Objekts abrufen. Dies ist mit den in den vorangegangenen Abschnitten beschriebenen Techniken möglich. Ein viel einfacherer Ansatz besteht jedoch darin, die Shell-Funktion SHBindToParent zu verwenden. Diese Funktion verwendet die vollqualifizierte PIDL eines Objekts und gibt einen angegebenen Schnittstellenzeiger im übergeordneten Ordner zurück. Optional gibt es auch die PIDL der einzelnen Ebene des Elements für die Verwendung in Methoden wie IShellFolder::GetAttributesOf zurück.

Die folgende Beispielkonsolenanwendung ruft die PIDL des Speziellen Systemordners ab und gibt den Anzeigenamen zurück.

#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>
#include <objbase.h>

int main()
{
    IShellFolder *psfParent = NULL;
    LPITEMIDLIST pidlSystem = NULL;
    LPCITEMIDLIST pidlRelative = NULL;
    STRRET strDispName;
    TCHAR szDisplayName[MAX_PATH];
    HRESULT hr;

    hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem);

    hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psfParent, &pidlRelative);

    if(SUCCEEDED(hr))
    {
        hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName);
        hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName));
        cout << "SHGDN_NORMAL - " <<szDisplayName << '\n';
    }

    psfParent->Release();
    CoTaskMemFree(pidlSystem);

    return 0;
}

Die Anwendung verwendet zuerst SHGetFolderLocation, um die PIDL des Systemordners abzurufen. Anschließend wird SHBindToParentaufgerufen aufgerufen, der einen Zeiger auf die IShellFolder-Schnittstelle des übergeordneten Ordners und die PIDL des Systemordners relativ zum übergeordneten Element zurückgibt. Anschließend wird die Methode IShellFolder::GetDisplayNameOf des übergeordneten Ordners verwendet, um den Anzeigenamen des Systemordners abzurufen. Da GetDisplayNameOf eine STRRET-Struktur zurückgibt, wird StrRetToBuf verwendet, um den Anzeigenamen in eine normale Zeichenfolge zu konvertieren. Nach dem Anzeigen des Anzeigenamens werden die Schnittstellenzeiger und die System-PIDL freigegeben. Beachten Sie, dass Sie die von SHBindToParentzurückgegebene relative PIDL nicht freigeben dürfen.