Verwenden der TAPI 3 MSP-Basisklassen
Im folgenden Verfahren wird beschrieben, wie Sie einen MSP mit atl Version 2.1 oder ATL Version 3.0 und den MSP-Basisklassen implementieren. Weitere Informationen und eine Liste der Bibliotheken und Header finden Sie unter TAPI 3 MSP-Basisklassen. Für den Inhalt dieses Themas wird davon ausgegangen, dass der Entwickler über ein funktionierendes Verständnis von ATL und COM verfügt und Erfahrung mit der Implementierung von COM-DLLs mit ATL hat.
So implementieren Sie und MSP mit ATL 2.1 oder ATL 3.0
Erstellen Sie eine IDL-Datei für Ihren MSP. Diese Datei definiert eine CLSID für Ihren MSP. Deklarieren Sie Ihre MSP-"Co-Klasse" als Implementierung der ITMSPAddress-Schnittstelle, und deklarieren Sie diese Schnittstelle als Standardschnittstelle für Ihr Klassenobjekt. Importieren Sie für die Definition von ITMSPAddress die Datei "msp.idl". Schließen Sie Ihre MSP-"Co-Klasse" in eine Typbibliothek für Ihren MSP ein. Wenn Ihr MSP private (benutzerdefinierte) Schnittstellen unterstützt, definieren Sie diese hier, und schließen Sie sie in Ihre Typbibliothek ein. Das folgende Codebeispiel ist eine IDL-Datei, wie oben beschrieben, ohne benutzerdefinierte Schnittstellen.
import "msp.idl"; [ uuid(4DDB6D35-3BC1-11d2-86F2-006008B0E5D2), version(2.0), helpstring("Wave MSP 2.0 Type Library") ] library WAVEMSPLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ uuid(4DDB6D36-3BC1-11d2-86F2-006008B0E5D2), helpstring("Wave MSP Class") ] coclass WaveMSP { [default] interface ITMSPAddress; }; };Ändern Sie Ihren TSP, um die CLSID Ihres MSP anzukündigen, wenn Tapi3.dll sie anfordert. Stellen Sie sicher, dass (1) Ihr TSP TAPI _ VERSION3 _ 0 oder höher in der TSPI-Funktion TSPI _ lineNegotiateTSPIVersionaushandeln kann, (2) In Ihrer TSP LINEDEVCAPS-Struktur ist das LINEDEVCAPFLAGS-MSP-Flag _ im dwDevCapFlags-Member festgelegt, und (3) Ihr TSP gibt Ihre MSP CLSID in der TSPI-Funktion TSPI _ lineMSPIdentifyzurück. Dies sollte die gleiche CLSID sein, die in Ihrer IDL-Datei angegeben ist. Beispielsweise die zweite Zeile "uuid" in der IDL-Beispieldatei im vorherigen Schritt.
Kompilieren Sie die MSPBase-Beispielanwendung im Platform Software Development Kit (SDK), um die Bibliothek MSPBaseSample.lib zu erstellen.
Verknüpfen Sie Ihre MSP-DLL mit der Bibliothek MSPBaseSample.lib.
Schließen Sie Mspbase.h aus dem SDK für MSP-Basisklassendefinitionen ein.
Implementieren Sie Ihre DLL-Exporte (z. B. DllMain). Microsoft Visual C++ werden diese für Sie generiert. Verwenden Sie in DllMain für DLL _ PROCESS _ ATTACH bzw. DLL PROCESS DETACH die _ _ Makros MSPLOGREGISTER und MSPLOGDEREGISTER, um Protokollierungsfunktionen für Ihre DLL zu aktivieren. Geben Sie den Namen Ihrer DLL im MSPLOGDEREGISTER-Aufruf an.
Verwenden Sie das in Msplog.h definierte LOG-Makro, um Ablaufverfolgungsmeldungen auf die gleiche Weise wie die Basisklassen auszugeben. Definieren Sie das MSPLOG-Präprozessorsymbol, um die Protokollierung in Ihre DLL einzubeziehen. Lassen Sie es nicht definiert, eine DLL ohne Protokollierung zu erstellen.
Leiten Sie eine Klasse von CMSPAddress ab, die Adressen für Ihren MSP implementiert. Deklarieren Sie eine globale ATL-Objektzuordnung, die ATL anweist, eine Instanz Ihrer Adressklasse zu erstellen, wenn Sie aufgefordert werden, CoCreate für die CLSID zu erstellen, die Sie in Ihrer IDL-Datei angegeben haben. Leiten Sie außerdem Ihre Adressklasse von der ATL CComCoClass-Vorlage ab, und fügen Sie eine DECLARE _ REGISTRY _ RESOURCEID-Deklaration in Ihre Adressklasse ein. Erstellen Sie ein entsprechendes Ressourcenskript und eine Headerdatei wie für jede andere ATL-COM-DLL.
Implementieren Sie die erforderlichen CMSPAddress-Überschreibungen für Ihre Adressklasse. Rufen Sie für MSPAddressAddRef und MSPAddressReleasedie bereitgestellten Hilfsfunktionsvorlagen auf. Geben Sie für GetCallMediaTypeseinfach eine DWORD-Bitmap mit all Ihren von MSP unterstützten TAPIMEDIAMODEs zurück. Geben Sie für CreateMSPCall und ShutdownMSPCallE NOTIMPL zurück, _ kompilieren und verknüpfen Sie Ihren MSP an diesem Punkt. Vergewissern Sie sich nun, dass Sie Ihren MSP über TAPI 3-Anwendungen registrieren und instanziieren können, aber keine erfolgreichen Aufrufe erstellen.
Leiten Sie eine Klasse von CMSPCallMultiGraph ab, um Ihre MSP-Aufrufobjekte zu implementieren. Es kann sinnvoll sein, von CMSPCallBase anstelle von CMSPCallMultiGraph abzuleiten, wenn das Modell filter-graph-per-stream nicht Ihren Anforderungen entspricht. Dies erhöht die Komplexität der Aufgabe (ab diesem Schreiben leiten alle MSPs Aufrufobjekte direkt von CMSPCallMultiGraph ab). Implementieren Sie in Ihrem Adressobjekt CreateMSPCall und ShutdownMSPCall, um Ihren spezifischen Aufrufobjekttyp mithilfe der bereitgestellten Hilfsfunktionsvorlagen zu erstellen und herunterzufahren. Überschreiben Sie in Ihrem Aufrufobjekt CreateStreamObject, um E _ NOTIMPL zurückzugeben. Überschreiben Sie MSPCallAddRef und MSPCallRelease auf die gleiche Weise wie die entsprechenden Adressmethoden. Auch hier sollten Sie in der Lage sein, Ihren MSP zu kompilieren und zu verknüpfen. Es sollte nun in der Lage sein, Aufrufe zu erstellen und herunterzufahren, aber die Aufrufe werden kein nützliches Streaming durchführen.
Leiten Sie eine Klasse von CMSPStream ab, um Ihre MSP-Streamobjekte zu implementieren. Implementieren Sie in Ihrem Aufrufobjekt CreateStreamObject, um Ihr Streamobjekt zu erstellen und zu initialisieren (in der Regel durch Aufrufen von ATL CreateInstance gefolgt von ATL _ InternalQueryInterface für ITStream, gefolgt von Aufruf von Init für Ihr Streamobjekt). Um eine feste Anzahl von Datenströmen zu unterstützen (dies ist üblich für MSPs, die keine Änderung von Streamkonfigurationen durch andere Endpunkte im Aufruf unterstützen), überschreiben Sie Init, CreateStreamund RemoveStream für Ihr Aufrufobjekt. (Der Aufruf von Init erstellt zunächst alle Ihre Streams, und CreateStream und RemoveStream geben die entsprechenden TAPI-Fehlercodes zurück, um zu verhindern, dass die Anwendung Streams erstellt oder entfernt.) Überschreiben Sie andernfalls die Init-Methode des Aufrufs, um eine anfängliche Standardkonfiguration von Streams mithilfe der für den Aufruf angeforderten Medientypen zu erstellen. Verwenden Sie beim Erstellen von Standardstreamobjekten in der Init-Methode Ihres Aufrufs die InternalCreateStream-Hilfsmethode.
Implementieren Sie Ihr Streamobjekt. Die einzige erforderliche Außerkraftsetzung ist die get _ Name-Methode, die einfach einen Anzeigenamen für den Stream zurückgibt. Darüber hinaus müssen Sie mehrere andere Methoden überschreiben. Welche Methoden überschrieben werden müssen, hängt von Ihrer Implementierung und davon ab, wann Sie die verschiedenen Aufgaben zum Erstellen und Dekonstruieren des Filterdiagramms ausführen möchten. Zu diesen Aufgaben gehören das Erstellen der entsprechenden Transportfilter, Codecs usw. sowie das Einfügen und Entfernen der Filterdiagramme zu den entsprechenden Zeiten. Sie müssen auch die ITTerminalControl-Schnittstelle für Terminalobjekte verwenden, um die ausgewählten Terminals mit Ihren Streams zu verbinden. Möglicherweise möchten Sie SelectTerminal und UnselectTerminal für Ihr Streamobjekt außer Kraft setzen, um die Terminalkonfigurationen einzuschränken, die ihre Streams akzeptieren. Das Beschränken jedes Streams auf ein einzelnes Terminal vereinfacht insbesondere die Erstellung Ihrer Filterdiagramme, aber die Anwendungsfunktionalität wie die Videovorschau wird eingeschränkt. Je nach Implementierung platzieren Sie die Graphkonstruktion, -dekonstruktion und den Terminalverbindungscode in den Methoden StartStream, StopStream, PauseStream, Initialize, Shutdown, SelectTerminalund UnselectTerminal oder in Ihren eigenen Methoden basierend auf der privaten TSP-Kommunikation. Beachten Sie, dass ein Stream ohne ausgewählte Terminals den gewünschten Diagrammzustand nachverfolgen muss. Ein StartStream-Aufruf gefolgt von einem SelectTerminal-Aufruf für einen solchen Stream muss zu einem Datenstrom führen. Überschreiben Sie die meisten dieser Methoden, um sicherzustellen, dass die richtige Konstruktion, Dekonstruktion, Verbindung und Trennung in jedem Fall abhängig vom Zustand des Streams erfolgt.
Implementieren Sie Ihre TSP-Kommunikation. Überschreiben Sie CMSPAddress::ReceiveTSPAddressData und/oder CMSPCallBase::ReceiveTSPCallData, und/oder durch Aufrufen von PostEvent für Ihr Adressobjekt oder HandleStreamEvent für Ihr Aufrufobjekt (entweder aus Ihrem Aufruf- oder Streamobjekt).
Verwenden Sie PostEvent für Ihr Adressobjekt oder HandleStreamEvent für Ihr Aufrufobjekt (entweder aus Ihrem Aufruf- oder Streamobjekt), um Aufrufmedienereignisse über Tapi3.dll an die Anwendung zu senden. Dies erfolgt in der Regel in Ihrem Streamobjekt in überschriebenen Methoden, einschließlich der Methoden ProcessGraphEvent, StopStream, StartStream, PauseStream, SelectTerminalund UnselectTerminal, je nachdem, wie Sie Ihre Streams implementieren.
Implementieren Sie alle gewünschten privaten Schnittstellen oder Unterstreams für Ihre vorhandenen Objekte (Adresse, Aufruf und Stream). Normalerweise gibt es keine. Beachten Sie, dass Sie beim Implementieren Ihrer privaten Schnittstellen die LIBID Ihrer Typbibliothek aus Ihrer IDL-Datei angeben. Das heißt, Anwendungsprogrammierer müssen Ihre MSP-Typbibliothek verwenden, wenn sie Ihre benutzerdefinierten Schnittstellen verwenden. Die in den MSP-Basisklassen implementierten MSP-Standardschnittstellen verwenden die Tapi3.dll LIBID und sind daher für alle TAPI 3-Anwendungen zugänglich.
Wenn Sie MSP-spezifische statische oder dynamische Terminalobjekte oder Ersetzungen für die statischen Standardterminals implementieren (nicht typisch), können Sie die bereitgestellten Terminalbasisklassen verwenden. Sie müssen verschiedene Methoden für Ihr Adressobjekt überschreiben, um alternative oder zusätzliche Methoden zum Erstellen von Terminalobjekten bereitzustellen.
Implementieren Sie die IObjectSafety-Schnittstelle für Ihre Address-, Call-, Stream- und Terminal-Objekte. Um dispatch mapper zum Abfragen von Schnittstellen für Ihre MSP-Objekte zu verwenden, markieren Sie Ihre Objekte als sicher für die Skripterstellung für diese Schnittstellen. Implementieren Sie hierzu die IObjectSafety-Schnittstelle für Ihr Objekt. Das Ableiten von CMSPObjectSafetyImpl (eine in Msputils.h bereitgestellte Hilfsklasse) und das Hinzufügen von IObjectSafety zur ATL-COM MAP Ihrer Klasse _ machen Ihre Objekte für skriptsichere Skripts auf allen Schnittstellen, die sie verfügbar machen. Beachten Sie, dass die Verwendung von Dispatch Mapper für MSP-Objekte implizit sein kann. MSP-Adresse und MSP-Aufruf werden durch TAPI-Adress- und TAPI-Aufrufobjekte aggregiert. Wenn dispatch mapper für die TAPI-Objekte verwendet wird, um die Schnittstellen abzufragen, die von den aggregierten MSP-Objekten verfügbar gemacht werden, werden die aggregierten MSP-Objekte zur Sicherheit der angeforderten Schnittstellen abgefragt.