Fragen eines Objekts nach einer Schnittstelle

Wir haben bereits gesehen, dass ein Objekt mehr als eine Schnittstelle implementieren kann. Das Common Item Dialog-Objekt ist ein praktisches Beispiel dafür. Um die gängigsten Verwendungen zu unterstützen, implementiert das -Objekt die IFileOpenDialog-Schnittstelle . Diese Schnittstelle definiert grundlegende Methoden zum Anzeigen des Dialogfelds und zum Abrufen von Informationen zur ausgewählten Datei. Für eine erweiterte Verwendung implementiert das -Objekt jedoch auch eine Schnittstelle mit dem Namen IFileDialogCustomize. Ein Programm kann diese Schnittstelle verwenden, um die Darstellung und das Verhalten des Dialogfelds anzupassen, indem es neue Benutzeroberflächensteuerelemente hinzufügt.

Denken Sie daran, dass jede COM-Schnittstelle direkt oder indirekt von der IUnknown-Schnittstelle erben muss. Das folgende Diagramm zeigt die Vererbung des Common Item Dialog-Objekts.

Diagramm, das Schnittstellen zeigt, die durch das Allgemeine Elementdialogobjekt verfügbar gemacht werden

Wie Sie im Diagramm sehen können, ist der direkte Vorgänger von IFileOpenDialog die IFileDialog-Schnittstelle , die wiederum IModalWindow erbt. Wenn Sie die Vererbungskette von IFileOpenDialog zu IModalWindow hochfahren, definieren die Schnittstellen zunehmend generalisierte Fensterfunktionen. Schließlich erbt die IModalWindow-SchnittstelleIUnknown. Das Common Item Dialog-Objekt implementiert auch IFileDialogCustomize, das in einer separaten Vererbungskette vorhanden ist.

Angenommen, Sie verfügen über einen Zeiger auf die IFileOpenDialog-Schnittstelle . Wie erhalten Sie einen Zeiger auf die IFileDialogCustomize-Schnittstelle ?

Diagramm, das zwei Schnittstellenzeiger auf Schnittstellen im selben Objekt zeigt

Das einfache Umwandeln des IFileOpenDialog-Zeigers in einen IFileDialogCustomize-Zeiger funktioniert nicht. Es gibt keine zuverlässige Möglichkeit zum "Kreuzumwandlung" über eine Vererbungshierarchie hinweg, ohne eine Form von Laufzeittypinformationen (RTTI), die ein stark sprachabhängiges Feature ist.

Der COM-Ansatz besteht darin, das -Objekt aufzufordern , Ihnen einen IFileDialogCustomize-Zeiger zu geben, wobei die erste Schnittstelle als Conduit in das -Objekt verwendet wird. Dies erfolgt durch Aufrufen der IUnknown::QueryInterface-Methode aus dem ersten Schnittstellenzeiger. Sie können sich QueryInterface als sprachunabhängige Version der dynamic_cast Schlüsselwort (keyword) in C++ vorstellen.

Die QueryInterface-Methode weist die folgende Signatur auf:

HRESULT QueryInterface(REFIID riid, void **ppvObject);

Basierend auf dem, was Sie bereits über CoCreateInstance wissen, können Sie möglicherweise erraten, wie QueryInterface funktioniert.

  • Der riid-Parameter ist die GUID, die die gewünschte Schnittstelle identifiziert. Der Datentyp REFIID ist eine Typdefinition für const GUID&. Beachten Sie, dass der Klassenbezeichner (CLSID) nicht erforderlich ist, da das Objekt bereits erstellt wurde. Nur der Schnittstellenbezeichner ist erforderlich.
  • Der ppvObject-Parameter empfängt einen Zeiger auf die Schnittstelle. Der Datentyp dieses Parameters ist void**, aus demselben Grund, aus dem CoCreateInstance diesen Datentyp verwendet: QueryInterface kann verwendet werden, um jede COM-Schnittstelle abzufragen, sodass der Parameter nicht stark typisiert werden kann.

So rufen Sie QueryInterface auf, um einen IFileDialogCustomize-Zeiger abzurufen:

hr = pFileOpen->QueryInterface(IID_IFileDialogCustomize, 
    reinterpret_cast<void**>(&pCustom));
if (SUCCEEDED(hr))
{
    // Use the interface. (Not shown.)
    // ...

    pCustom->Release();
}
else
{
    // Handle the error.
}

Überprüfen Sie wie immer den HRESULT-Rückgabewert , falls die Methode fehlschlägt. Wenn die Methode erfolgreich ist, müssen Sie Release aufrufen, wenn Sie den Zeiger verwenden, wie unter Verwalten der Lebensdauer eines Objekts beschrieben.

Nächste

Speicherbelegung in COM