Share via


Gerätetopologien

Die DeviceTopology-API ermöglicht Clients die Kontrolle über eine Vielzahl interner Funktionen von Audioadaptern, auf die sie nicht über die MMDevice-API, die WASAPI oder die EndpointVolume-API zugreifen können.

Wie bereits erläutert, stellen die MMDevice-API, WASAPI und die EndpointVolume-API Mikrofone , Lautsprecher, Kopfhörer und andere Audioeingabe- und Ausgabegeräte für Clients als Audioendpunktgeräte bereit. Das Endpunktgerätemodell bietet Clients bequemen Zugriff auf Volume- und Stummschaltungssteuerelemente in Audiogeräten. Clients, die nur diese einfachen Steuerelemente benötigen, können das Durchlaufen der internen Topologien von Hardwaregeräten in Audioadaptern vermeiden.

In Windows Vista konfiguriert die Audio-Engine automatisch die Topologien von Audiogeräten für die Verwendung durch Audioanwendungen. Daher müssen Anwendungen selten, wenn überhaupt, die DeviceTopology-API für diesen Zweck verwenden. Angenommen, ein Audioadapter enthält einen Eingabe-Multiplexer, der einen Datenstrom entweder von einer Zeileneingabe oder einem Mikrofon erfassen kann, der jedoch keine Streams von beiden Endpunktgeräten gleichzeitig erfassen kann. Angenommen, der Benutzer hat Anwendungen im exklusiven Modus aktiviert, um die Verwendung eines Audioendpunktgeräts durch Anwendungen im freigegebenen Modus zu verdutzen, wie unter Datenströme im exklusiven Modus beschrieben. Wenn eine Anwendung im freigegebenen Modus einen Datenstrom aus der Zeileneingabe aufzeichnet, wenn eine Anwendung im exklusiven Modus mit der Aufzeichnung eines Datenstroms aus dem Mikrofon beginnt, wechselt das Audiomodul den Multiplexer automatisch von der Zeileneingabe zum Mikrofon. In früheren Versionen von Windows, einschließlich Windows XP, verwendet die Anwendung im exklusiven Modus in diesem Beispiel die MixerXxx-Funktionen in der Windows-Multimedia-API, um die Topologien der Adaptergeräte zu durchlaufen, den Multiplexer zu ermitteln und den Multiplexer für die Auswahl der Mikrofoneingabe zu konfigurieren. In Windows Vista sind diese Schritte nicht mehr erforderlich.

Einige Clients erfordern jedoch möglicherweise eine explizite Kontrolle über Typen von Audiohardwaresteuerelementen, auf die nicht über die MMDevice-API, die WASAPI oder die EndpointVolume-API zugegriffen werden kann. Für diese Clients bietet die DeviceTopology-API die Möglichkeit, die Topologien von Adaptergeräten zu durchlaufen, um die Audiosteuerelemente auf den Geräten zu ermitteln und zu verwalten. Anwendungen, die die DeviceTopology-API verwenden, müssen sorgfältig entworfen werden, um zu vermeiden, dass die Windows-Audiorichtlinie beeinträchtigt wird und die internen Konfigurationen von Audiogeräten, die für andere Anwendungen freigegeben werden, gestört werden. Weitere Informationen zur Windows-Audiorichtlinie finden Sie unter Audiokomponenten im Benutzermodus.

Die DeviceTopology-API bietet Schnittstellen zum Ermitteln und Verwalten der folgenden Arten von Audiosteuerelementen in einer Gerätetopologie:

  • Automatische Verstärkungssteuerung
  • Basssteuerung
  • Eingabeauswahl (Multiplexer)
  • Lautstärkeregelung
  • Midrange-Steuerelement
  • Stummschaltsteuerung
  • Ausgabeauswahl (Demultiplexer)
  • Peak-Meter
  • Treble-Steuerelement
  • Lautstärkeregelung

Darüber hinaus ermöglicht die DeviceTopology-API Clients das Abfragen von Adaptergeräten nach Informationen zu den Streamformaten, die sie unterstützen. Die Headerdatei Devicetopology.h definiert die Schnittstellen in der DeviceTopology-API.

Das folgende Diagramm zeigt ein Beispiel für mehrere verbundene Gerätetopologien für den Teil eines PCI-Adapters, der Audio von einem Mikrofon, einer Leitungseingabe und einem CD-Player erfasst.

Beispiel für vier Verbundene Gerätetopologien

Das obige Diagramm zeigt die Datenpfade, die von den analogen Eingängen zum Systembus führen. Jedes der folgenden Geräte wird als Gerätetopologieobjekt mit einer IDeviceTopology-Schnittstelle dargestellt:

  • Wave Capture-Gerät
  • Eingabe-Multiplexergerät
  • Endpunktgerät A
  • Endpunktgerät B

Beachten Sie, dass das Topologiediagramm Adaptergeräte (die Wave Capture- und Eingabemultixergeräte) mit Endpunktgeräten kombiniert. Über die Verbindungen zwischen Geräten werden Audiodaten von einem Gerät zum nächsten weitergeleitet. Auf jeder Seite einer Verbindung befindet sich ein Connector (im Diagramm als Con bezeichnet), über den Daten in ein Gerät gelangen oder dieses verlassen.

Am linken Rand des Diagramms gelangen Signale von den Zeileneingangs- und Mikrofonbuchsen in die Endpunktgeräte.

Innerhalb des Wave Capture-Geräts und des Eingabemultiplixers befinden sich Streamverarbeitungsfunktionen, die in der Terminologie der DeviceTopology-API als Untereinheiten bezeichnet werden. Die folgenden Arten von Untereinheiten werden im vorherigen Diagramm angezeigt:

  • Lautstärkeregelung (als Vol bezeichnet)
  • Stummschaltsteuerelement (als Stummschaltung bezeichnet)
  • Multiplexer (oder Eingabeauswahl; beschriftet MUX)
  • Analog-Digital-Konverter (beschriftet ADC)

Die Einstellungen in den Volume-, Stummschaltungs- und Multiplexeruntereinheiten können von Clients gesteuert werden, und die DeviceTopology-API stellt Steuerungsschnittstellen für Clients zum Steuern bereit. In diesem Beispiel verfügt die ADC-Untereinheit über keine Steuerungseinstellungen. Daher stellt die DeviceTopology-API keine Steuerungsschnittstelle für den ADC bereit.

In der Terminologie der DeviceTopology-API gehören Connectors und Untereinheiten zur gleichen allgemeinen Kategorie – Teilen. Alle Teile, unabhängig davon, ob es sich um Connectors oder Untereinheiten handelt, stellen einen gemeinsamen Satz von Funktionen bereit. Die DeviceTopology-API implementiert eine IPart-Schnittstelle , um die generischen Funktionen darzustellen, die für Connectors und Untereinheiten gemeinsam sind. Die API implementiert die IConnector- und ISubunit-Schnittstellen , um die spezifischen Aspekte von Connectors und Untereinheiten darzustellen.

Die DeviceTopology-API erstellt die Topologien des Wave Capture-Geräts und des Eingabemultiplixergeräts aus den Kernelstreamingfiltern (KS), die der Audiotreiber für das Betriebssystem zur Darstellung dieser Geräte verfügbar macht. (Der Audioadaptertreiber implementiert IMiniportWaveXxx - und IMiniportTopology-Schnittstellen , um die hardwareabhängigen Teile dieser Filter darzustellen. Weitere Informationen zu diesen Schnittstellen und zu KS-Filtern finden Sie in der Windows DDK-Dokumentation.)

Die DeviceTopology-API erstellt triviale Topologien, um die Endpunktgeräte A und B im vorherigen Diagramm darzustellen. Die Gerätetopologie eines Endpunktgeräts besteht aus einem einzelnen Connector. Diese Topologie ist lediglich ein Platzhalter für das Endpunktgerät und enthält keine Untereinheiten für die Verarbeitung von Audiodaten. Tatsächlich enthalten Adaptergeräte alle Untereinheiten, die Clientanwendungen zum Steuern der Audioverarbeitung verwenden. Die Gerätetopologie eines Endpunktgeräts dient in erster Linie als Ausgangspunkt für die Untersuchung der Gerätetopologien von Adaptergeräten.

Interne Verbindungen zwischen zwei Teilen in einer Gerätetopologie werden als Links bezeichnet. Die DeviceTopology-API bietet Methoden zum Durchlaufen von Links von einem Teil zum nächsten in einer Gerätetopologie. Die API stellt auch Methoden zum Durchlaufen der Verbindungen zwischen Gerätetopologien bereit.

Um mit der Untersuchung einer Reihe verbundener Gerätetopologien zu beginnen, aktiviert eine Clientanwendung die IDeviceTopology-Schnittstelle eines Audioendpunktgeräts. Der Connector in einem Endpunktgerät stellt entweder eine Verbindung mit einem Connector in einem Audioadapter oder mit einem Netzwerk her. Wenn der Endpunkt eine Verbindung mit einem Gerät auf einem Audioadapter herstellt, ermöglichen die Methoden in der DeviceTopology-API der Anwendung das Durchlaufen der Verbindung vom Endpunkt zum Adapter, indem sie einen Verweis auf die IDeviceTopology-Schnittstelle des Adaptergeräts auf der anderen Seite der Verbindung abrufen. Ein Netzwerk verfügt dagegen über keine Gerätetopologie. Eine Netzwerkverbindung leitet einen Audiostream an einen Client, der remote auf das System zugreift.

Die DeviceTopology-API bietet nur Zugriff auf die Topologien der Hardwaregeräte in einem Audioadapter. Die externen Geräte am linken Rand des Diagramms und die Softwarekomponenten am rechten Rand liegen außerhalb des Bereichs der API. Die gestrichelten Linien auf beiden Seiten des Diagramms stellen die Grenzwerte der DeviceTopology-API dar. Der Client kann die API verwenden, um einen Datenpfad zu untersuchen, der sich von der Eingabebuchse bis zum Systembus erstreckt, aber die API kann diese Grenzen nicht überschreiten.

Jeder Connector im vorherigen Diagramm weist einen zugeordneten Verbindungstyp auf, der den Verbindungstyp angibt, den der Connector herstellt. So weisen die Stecker an den beiden Seiten einer Verbindung immer identische Verbindungstypen auf. Der Verbindungstyp wird durch einen ConnectorType-Enumerationswert angegeben– Physical_External, Physical_Internal, Software_Fixed, Software_IO oder Network. Die Verbindungen zwischen dem Eingabe-Multiplexergerät und den Endpunktgeräten A und B sind vom Typ Physical_External, was bedeutet, dass die Verbindung eine physische Verbindung mit einem externen Gerät darstellt (d. h. eine vom Benutzer zugängliche Audiobuchse). Die Verbindung mit dem analogen Signal vom internen CD-Player ist vom Typ Physical_Internal, was auf eine physische Verbindung mit einem Hilfsgerät hinweist, das im Systemgehäuse installiert ist. Die Verbindung zwischen dem Wellenerfassungsgerät und dem Eingabe-Multiplexergerät ist vom Typ Software_Fixed, was auf eine dauerhafte Verbindung hinweist, die fest ist und nicht unter Softwaresteuerung konfiguriert werden kann. Schließlich ist die Verbindung mit dem Systembus auf der rechten Seite des Diagramms vom Typ Software_IO, was angibt, dass die Daten-E/A für die Verbindung von einer DMA-Engine unter Softwaresteuerung implementiert wird. (Das Diagramm enthält kein Beispiel für einen Netzwerkverbindungstyp.)

Der Client beginnt mit der Durchquerung eines Datenpfads auf dem Endpunktgerät. Zunächst ruft der Client eine IMMDevice-Schnittstelle ab, die das Endpunktgerät darstellt, wie unter Enumerating Audio Devices erläutert. Um die IDeviceTopology-Schnittstelle für das Endpunktgerät abzurufen, ruft der Client die IMMDevice::Activate-Methode auf, wobei parameter iid auf REFIID IID_IDeviceTopology festgelegt ist.

Im Beispiel im vorherigen Diagramm enthält das Eingabemultimultixergerät alle Hardwaresteuerelemente (Lautstärke, Stummschaltung und Multiplexer) für die Aufzeichnungsstreams aus den Zeileneingabe- und Mikrofonbuchsen. Das folgende Codebeispiel zeigt, wie Sie die IDeviceTopology-Schnittstelle für das Eingabemultiplixergerät von der IMMDevice-Schnittstelle für das Endpunktgerät für die Zeileneingabe oder das Mikrofon abrufen:

//-----------------------------------------------------------
// The input argument to this function is a pointer to the
// IMMDevice interface of an endpoint device. The function
// outputs a pointer (counted reference) to the
// IDeviceTopology interface of the adapter device that
// connects to the endpoint device.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hres)  \
              if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk)  \
              if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }

const IID IID_IDeviceTopology = __uuidof(IDeviceTopology);
const IID IID_IPart = __uuidof(IPart);

HRESULT GetHardwareDeviceTopology(
            IMMDevice *pEndptDev,
            IDeviceTopology **ppDevTopo)
{
    HRESULT hr = S_OK;
    IDeviceTopology *pDevTopoEndpt = NULL;
    IConnector *pConnEndpt = NULL;
    IConnector *pConnHWDev = NULL;
    IPart *pPartConn = NULL;

    // Get the endpoint device's IDeviceTopology interface.

    hr = pEndptDev->Activate(
                      IID_IDeviceTopology, CLSCTX_ALL,
                      NULL, (void**)&pDevTopoEndpt);
    EXIT_ON_ERROR(hr)

    // The device topology for an endpoint device always
    // contains just one connector (connector number 0).

    hr = pDevTopoEndpt->GetConnector(0, &pConnEndpt);
    EXIT_ON_ERROR(hr)

    // Use the connector in the endpoint device to get the
    // connector in the adapter device.

    hr = pConnEndpt->GetConnectedTo(&pConnHWDev);
    EXIT_ON_ERROR(hr)

    // Query the connector in the adapter device for
    // its IPart interface.

    hr = pConnHWDev->QueryInterface(
                         IID_IPart, (void**)&pPartConn);
    EXIT_ON_ERROR(hr)

    // Use the connector's IPart interface to get the
    // IDeviceTopology interface for the adapter device.

    hr = pPartConn->GetTopologyObject(ppDevTopo);

Exit:
    SAFE_RELEASE(pDevTopoEndpt)
    SAFE_RELEASE(pConnEndpt)
    SAFE_RELEASE(pConnHWDev)
    SAFE_RELEASE(pPartConn)

    return hr;
}

Die GetHardwareDeviceTopology-Funktion im vorherigen Codebeispiel führt die folgenden Schritte aus, um die IDeviceTopology-Schnittstelle für das Eingabemultiplixergerät abzurufen:

  1. Rufen Sie die IMMDevice::Activate-Methode auf, um die IDeviceTopology-Schnittstelle für das Endpunktgerät abzurufen.
  2. Rufen Sie mit der IDeviceTopology-Schnittstelle , die im vorherigen Schritt abgerufen wurde, die IDeviceTopology::GetConnector-Methode auf, um die IConnector-Schnittstelle des einzelnen Connectors (Connectornummer 0) im Endpunktgerät abzurufen.
  3. Rufen Sie mit der im vorherigen Schritt abgerufenen IConnector-Schnittstelle die IConnector::GetConnectedTo-Methode auf, um die IConnector-Schnittstelle des Connectors im Eingabemultimultixergerät abzurufen.
  4. Fragen Sie die im vorherigen Schritt abgerufene IConnector-Schnittstelle für ihre IPart-Schnittstelle ab.
  5. Rufen Sie mit der IPart-Schnittstelle , die im vorherigen Schritt abgerufen wurde, die IPart::GetTopologyObject-Methode auf, um die IDeviceTopology-Schnittstelle für das Eingabemultiplixergerät abzurufen.

Bevor der Benutzer im vorherigen Diagramm vom Mikrofon aufzeichnen kann, muss die Clientanwendung sicherstellen, dass der Multiplexer die Mikrofoneingabe auswählt. Das folgende Codebeispiel zeigt, wie ein Client den Datenpfad vom Mikrofon durchlaufen kann, bis er den Multiplexer findet, den er dann programmiert, um die Mikrofoneingabe auszuwählen:

//-----------------------------------------------------------
// The input argument to this function is a pointer to the
// IMMDevice interface for a capture endpoint device. The
// function traverses the data path that extends from the
// endpoint device to the system bus (for example, PCI)
// or external bus (USB). If the function discovers a MUX
// (input selector) in the path, it selects the MUX input
// that connects to the stream from the endpoint device.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hres)  \
              if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk)  \
              if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }

const IID IID_IDeviceTopology = __uuidof(IDeviceTopology);
const IID IID_IPart = __uuidof(IPart);
const IID IID_IConnector = __uuidof(IConnector);
const IID IID_IAudioInputSelector = __uuidof(IAudioInputSelector);

HRESULT SelectCaptureDevice(IMMDevice *pEndptDev)
{
    HRESULT hr = S_OK;
    DataFlow flow;
    IDeviceTopology *pDeviceTopology = NULL;
    IConnector *pConnFrom = NULL;
    IConnector *pConnTo = NULL;
    IPart *pPartPrev = NULL;
    IPart *pPartNext = NULL;
    IAudioInputSelector *pSelector = NULL;

    if (pEndptDev == NULL)
    {
        EXIT_ON_ERROR(hr = E_POINTER)
    }

    // Get the endpoint device's IDeviceTopology interface.
    hr = pEndptDev->Activate(
                      IID_IDeviceTopology, CLSCTX_ALL, NULL,
                      (void**)&pDeviceTopology);
    EXIT_ON_ERROR(hr)

    // The device topology for an endpoint device always
    // contains just one connector (connector number 0).
    hr = pDeviceTopology->GetConnector(0, &pConnFrom);
    SAFE_RELEASE(pDeviceTopology)
    EXIT_ON_ERROR(hr)

    // Make sure that this is a capture device.
    hr = pConnFrom->GetDataFlow(&flow);
    EXIT_ON_ERROR(hr)

    if (flow != Out)
    {
        // Error -- this is a rendering device.
        EXIT_ON_ERROR(hr = AUDCLNT_E_WRONG_ENDPOINT_TYPE)
    }

    // Outer loop: Each iteration traverses the data path
    // through a device topology starting at the input
    // connector and ending at the output connector.
    while (TRUE)
    {
        BOOL bConnected;
        hr = pConnFrom->IsConnected(&bConnected);
        EXIT_ON_ERROR(hr)

        // Does this connector connect to another device?
        if (bConnected == FALSE)
        {
            // This is the end of the data path that
            // stretches from the endpoint device to the
            // system bus or external bus. Verify that
            // the connection type is Software_IO.
            ConnectorType  connType;
            hr = pConnFrom->GetType(&connType);
            EXIT_ON_ERROR(hr)

            if (connType == Software_IO)
            {
                break;  // finished
            }
            EXIT_ON_ERROR(hr = E_FAIL)
        }

        // Get the connector in the next device topology,
        // which lies on the other side of the connection.
        hr = pConnFrom->GetConnectedTo(&pConnTo);
        EXIT_ON_ERROR(hr)
        SAFE_RELEASE(pConnFrom)

        // Get the connector's IPart interface.
        hr = pConnTo->QueryInterface(
                        IID_IPart, (void**)&pPartPrev);
        EXIT_ON_ERROR(hr)
        SAFE_RELEASE(pConnTo)

        // Inner loop: Each iteration traverses one link in a
        // device topology and looks for input multiplexers.
        while (TRUE)
        {
            PartType parttype;
            UINT localId;
            IPartsList *pParts;

            // Follow downstream link to next part.
            hr = pPartPrev->EnumPartsOutgoing(&pParts);
            EXIT_ON_ERROR(hr)

            hr = pParts->GetPart(0, &pPartNext);
            pParts->Release();
            EXIT_ON_ERROR(hr)

            hr = pPartNext->GetPartType(&parttype);
            EXIT_ON_ERROR(hr)

            if (parttype == Connector)
            {
                // We've reached the output connector that
                // lies at the end of this device topology.
                hr = pPartNext->QueryInterface(
                                  IID_IConnector,
                                  (void**)&pConnFrom);
                EXIT_ON_ERROR(hr)

                SAFE_RELEASE(pPartPrev)
                SAFE_RELEASE(pPartNext)
                break;
            }

            // Failure of the following call means only that
            // the part is not a MUX (input selector).
            hr = pPartNext->Activate(
                              CLSCTX_ALL,
                              IID_IAudioInputSelector,
                              (void**)&pSelector);
            if (hr == S_OK)
            {
                // We found a MUX (input selector), so select
                // the input from our endpoint device.
                hr = pPartPrev->GetLocalId(&localId);
                EXIT_ON_ERROR(hr)

                hr = pSelector->SetSelection(localId, NULL);
                EXIT_ON_ERROR(hr)

                SAFE_RELEASE(pSelector)
            }

            SAFE_RELEASE(pPartPrev)
            pPartPrev = pPartNext;
            pPartNext = NULL;
        }
    }

Exit:
    SAFE_RELEASE(pConnFrom)
    SAFE_RELEASE(pConnTo)
    SAFE_RELEASE(pPartPrev)
    SAFE_RELEASE(pPartNext)
    SAFE_RELEASE(pSelector)
    return hr;
}

Die DeviceTopology-API implementiert eine IAudioInputSelector-Schnittstelle , um einen Multiplexer zu kapseln, z. B. den im vorherigen Diagramm. (Eine IAudioOutputSelector-Schnittstelle kapselt einen Demultiplexer.) Im vorherigen Codebeispiel fragt die innere Schleife der SelectCaptureDevice-Funktion jede gefundene Untereinheit ab, um zu ermitteln, ob es sich bei der Untereinheit um einen Multiplexer handelt. Wenn es sich bei der Untereinheit um einen Multiplexer handelt, ruft die Funktion die IAudioInputSelector::SetSelection-Methode auf, um die Eingabe auszuwählen, die vom Endpunktgerät aus eine Verbindung mit dem Stream herstellt.

Im vorherigen Codebeispiel durchläuft jede Iteration der äußeren Schleife eine Gerätetopologie. Beim Durchlaufen der Gerätetopologien im vorherigen Diagramm durchläuft die erste Iteration das Eingabemultimultixergerät, und die zweite Iteration durchläuft das Wellenerfassungsgerät. Die Funktion wird beendet, wenn sie den Connector am rechten Rand des Diagramms erreicht. Die Beendigung tritt auf, wenn die Funktion einen Connector mit einem Software_IO Verbindungstyp erkennt. Dieser Verbindungstyp gibt den Punkt an, an dem das Adaptergerät eine Verbindung mit dem Systembus herstellt.

Der Aufruf der IPart::GetPartType-Methode im vorherigen Codebeispiel ruft einen IPartType-Enumerationswert ab, der angibt, ob es sich bei dem aktuellen Teil um einen Connector oder eine Audioverarbeitungsuntereinheit handelt.

Die innere Schleife im vorherigen Codebeispiel führt schritte über den Link von einem Teil zum nächsten durch Aufrufen der IPart::EnumPartsOutgoing-Methode . (Es gibt auch eine IPart::EnumPartsIncoming-Methode , um in die entgegengesetzte Richtung zu springen.) Diese Methode ruft ein IPartsList-Objekt ab, das eine Liste aller ausgehenden Teile enthält. Jedes Teil, von dem die SelectCaptureDevice-Funktion erwartet, dass er in einem Erfassungsgerät auftritt, weist jedoch immer genau einen ausgehenden Teil auf. Daher fordert der nachfolgende Aufruf von IPartsList::GetPart immer den ersten Teil der Liste an, Teilnummer 0, da die Funktion davon ausgeht, dass dies der einzige Teil in der Liste ist.

Wenn die SelectCaptureDevice-Funktion auf eine Topologie stößt, für die diese Annahme nicht gültig ist, kann die Funktion das Gerät möglicherweise nicht ordnungsgemäß konfigurieren. Um einen solchen Fehler zu vermeiden, kann eine allgemeinere Version der Funktion die folgenden Schritte ausführen:

  • Rufen Sie die IPartsList::GetCount-Methode auf, um die Anzahl der ausgehenden Teile zu bestimmen.
  • Rufen Sie für jedes ausgehende Teil IPartsList::GetPart auf, um mit der Durchquerung des Datenpfads zu beginnen, der aus dem Teil führt.

Einige, aber nicht unbedingt alle Teile verfügen über zugehörige Hardwaresteuerelemente, die Clients festlegen oder abrufen können. Ein bestimmtes Teil kann 0, ein oder mehrere Hardwaresteuerelemente aufweisen. Ein Hardwaresteuerelement wird durch das folgende Schnittstellenpaar dargestellt:

  • Eine generische Steuerungsschnittstelle, IControlInterface, mit Methoden, die allen Hardwaresteuerelementen gemeinsam sind.
  • Eine funktionsspezifische Schnittstelle (z . B. IAudioVolumeLevel), die die Steuerungsparameter für einen bestimmten Typ von Hardwaresteuerung verfügbar macht (z. B. eine Lautstärkesteuerung).

Um die Hardwaresteuerelemente für ein Teil aufzulisten, ruft der Client zuerst die IPart::GetControlInterfaceCount-Methode auf, um die Anzahl der Hardwaresteuerelemente zu bestimmen, die dem Teil zugeordnet sind. Als Nächstes führt der Client eine Reihe von Aufrufen der IPart::GetControlInterface-Methode aus, um die IControlInterface-Schnittstelle für jedes Hardwaresteuerelement abzurufen. Schließlich ruft der Client die funktionsspezifische Schnittstelle für jedes Hardwaresteuerelement ab, indem er die IControlInterface::GetIID-Methode aufruft, um die Schnittstellen-ID abzurufen. Der Client ruft die IPart::Activate-Methode mit dieser ID auf, um die funktionsspezifische Schnittstelle abzurufen.

Ein Teil, der ein Connector ist, kann eine der folgenden funktionsspezifischen Steuerungsschnittstellen unterstützen:

Ein Teil, der eine Untereinheit ist, kann eine oder mehrere der folgenden funktionsspezifischen Steuerelementschnittstellen unterstützen:

Ein Teil unterstützt die IDeviceSpecificProperty-Schnittstelle nur, wenn das zugrunde liegende Hardwaresteuerelement über einen gerätespezifischen Steuerungswert verfügt und das Steuerelement durch keine andere funktionsspezifische Schnittstelle in der vorherigen Liste angemessen dargestellt werden kann. In der Regel ist eine gerätespezifische Eigenschaft nur für einen Client nützlich, der die Bedeutung des Eigenschaftswerts aus Informationen wie dem Teiletyp, dem Teiluntertyp und dem Teilenamen ableiten kann. Der Client kann diese Informationen abrufen, indem er die Methoden IPart::GetPartType, IPart::GetSubType und IPart::GetName aufruft.

Programmierhandbuch