Manchmal muss unsere COM-Komponente eine Benachrichtigung an den Client senden oder die Rückruffunktion aufrufen. Das Schema ist einfach: Die Komponente veröffentlicht die Schnittstelle, der Client erstellt ein von der Schnittstelle geerbtes Objekt und übergibt es an die Komponente. Die Komponente ruft wiederum die Schnittstellenfunktionen auf und ruft damit die Funktionen auf der Clientseite auf.
Im Fall von Visual Basic oder Visual Basic für Anwendungen können wir eine Klasse schreiben, die von einer beliebigen Schnittstelle geerbt wurde. Dies ist jedoch für VBScript-Skriptdateien nicht möglich.
Hier eilt uns die IDispatch Schnittstelle zu Hilfe. Über diese Schnittstelle übernimmt unsere leistungsstarke Komponente demütig die bescheidene Rolle eines Clients, und aus einem kleinen Skript wird ein echter Automatisierungsserver.
Wir werden die Komponente in der Programmiersprache FreeBASIC entwickeln.
Klassen in der Skriptdatei
Sie können Klassen in Skriptdateien deklarieren und verwenden. Solche Klassen werden implizit von der IDispatch Schnittstelle geerbt und sind echte COM-Klassen.
Wir deklarieren eine Klasse, deren Instanz wir anschließend an unsere Komponente übergeben werden:
 Class CallBack Function CallBack(Param)  
Unsere Komponente empfängt eine Instanz der CallBack Klasse, ruft die CallBack Funktion auf und CallBack ihr eine Zeichenfolge mit Text im Parameter.
 
IDispatch
Diese Schnittstelle ist der Stolperstein der Automatisierung. Normalerweise basiert die Implementierung von IDispatch auf einer ITypeInfo->Invoke über ITypeInfo->Invoke oder die Funktion CreateStdDispatch In diesem Fall befindet sich der Automatisierungsserver jedoch in einem Skript und verfügt nicht über eine CreateStdDispatch Unsere Komponente fungiert als Client. Zur Vereinfachung funktioniert IDipatch : IDipatch den Namen der Funktion und überträgt die Kontrolle an sie.
Die Definition der Schnittstelle liegt in der Überschrift „oaidl.bi“ (Einrückungen und Zeilenumbrüche werden zur besseren Lesbarkeit hinzugefügt):
 Type IDispatch As IDispatch_ Type LPDISPATCH As IDispatch Ptr Type IDispatchVtbl  
Die Funktionen GetIDsOfNames und Invoke sind in dieser Schnittstelle am interessantesten.
GetIDsOfNames
Es nimmt den Namen der Funktion und gibt ihre DISPID . DISPID ist ein Alias für den Typ LONG .
Aus Sicht des DISPID ist DISPID lediglich ein Optimierungswerkzeug, das das Übergeben von Zeichenfolgen vermeidet. Für den Server ist DISPID die Kennung der Funktion, die der Client aufrufen möchte.
Rufen Sie auf
Per Versand führt die Kennung die entsprechende Funktion aus.
DISPPARAMS
Diese Struktur enthält die Parameter der aufgerufenen Funktion. Alle Parameter sind in VARIANT .
 Type tagDISPPARAMS  
Um den Code zu vereinfachen, verwenden wir keine benannten Argumente, sondern setzen stattdessen NULL .
Komponente
Für die Verwendung in Skripten sollten Komponenten auch direkt oder indirekt von IDipatch erben.
ITestCOMServer-Schnittstelle
Erstellen ITestCOMServer die ITestCOMServer Schnittstelle mit zwei Funktionen, SetCallBack und InvokeCallBack . Der erste speichert das Automatisierungsserverobjekt, der zweite ruft die Objektfunktion auf.
 Type ITestCOMServer As ITestCOMServer_ Type LPITESTCOMSERVER As ITestCOMServer Ptr Type ITestCOMServerVirtualTable  
Klasse TestCOMServer
Jetzt können Sie eine COM-Klasse deklarieren:
 Type TestCOMServer  
Funktionsrückruf
Die Implementierung der SetCallBack Funktion SetCallBack einfach: Wir speichern das vom Client übertragene Automatisierungsserverobjekt und den Funktionsaufrufparameter.
 Function TestCOMServerSetCallBack( _ ByVal pTestCOMServer As TestCOMServer Ptr, _ ByVal CallBack As IDispatch Ptr, _ ByVal UserName As BSTR _ )As HRESULT  
InvokeCallBack-Funktion
Die InvokeCallBack Funktion InvokeCallBack jedoch hart arbeiten. Zuerst müssen Sie die Dispatcher- CallBack der CallBack Funktion des Automatisierungsservers CallBack .
 Function TestCOMServerInvokeCallBack( _ ByVal pTestCOMServer As TestCOMServer Ptr _ )As HRESULT If pTestCOMServer->CallBack = NULL Then Return E_POINTER End If  
Nachdem die DISPID Funktion empfangen wurde, kann sie aufgerufen werden:
   
Fazit
Wie Sie sehen, kann eine Komponente auch mit einer Skriptdatei Feedback erhalten. Dies ist nützlich, um den Client über abgeschlossene Vorgänge durch die Komponente zu informieren.
Klassen in Skripten können in der Registrierung registriert werden. In diesem Fall sind sie mit ProgID für das gesamte System ProgID . Dies ist jedoch eine ganz andere Geschichte.
Referenzen
Projektcode auf der Github-Site: https://github.com/zamabuvaraeu/TestCOMServer
PS Irgendwie verschwand das Highlight für die BASIC-Syntax, stattdessen wurde VBScript verwendet, und einige Operatoren werden damit nicht hervorgehoben.