Pluginprogrammierung DMXC2
Dieses Wikiartikel wurde aus mehreren, vermutlich veralteten, Wikiartikeln aus dem alten Wiki übertragen. Daher können einige Informationen nicht mehr stimmen oder unvollständig sein. |
Inhaltsverzeichnis
In welcher Umgebung kann man eine Plugin-dll entwickeln?
In unserem Projekt arbeiten wir mit Visual Basic 6. [Microsoft] stellte ein kostenloses Ablaufmodell zur Verfügung, (welche ich leider nicht mehr finde und die man heute wohl nur noch auf CDs alter PC-Zeitschriften bekommt). Das ist ein vollwertiges Basic, aber leider kann man damit keine .exe oder dll erzeugen, sondern der Code wird in einer Interpreterumgebung ausgeführt.
Zur Erzeugung von dlls benötigt man z.B. die "Visual Basic Enterprise Edition", die aber nicht mehr im Handel ist, aber sehr häufig bei ebay legal angeboten wird. Für Schüler und Studenten gab es auch eine günstige Version bei [Amazon]. Möglicherweise können sich einige Nutzer sich diese Version aber auch über das MSDN beziehen.
Alternativ gibt es folgende potenzielle Möglichkeiten zur Erzegung von dlls:
- Es gab von Microsoft auch die kostenlose "Control Creation Edition". Auch diese gibt es anscheinend nicht mehr offiziell, aber dank google findet man das noch im Internet. Im Internet und in PC-Zeitschriften kursieren legale Tricks, wie man damit auch .exe generiert. Welcher Entwickler probiert mal aus, ob das auch für plugins funktioniert?
- Plugins können prinzipiell auch in jeder anderen Sprache geschrieben werden, in der ein Compiler zur Verfügung steht. Wurde teilweise erfolgreich mit Delphi ausprobiert.
- Man verwendet das .NET Framework SDK, welches viele kostenlose hilfreiche Tools enthält, z.B. einen Compiler für Visual Basic.NET. Leider ist die zugehörige Entwicklungsumgebung nicht kostenlos, da schafft aber der nächste Punkt eventuell Abhilfe.
- Es gibt die kostenlose Entwicklungsumgebung SharpDevelop als (wie ich gelesen habe) hervorragende Alternative. Der Name täuscht - diese Umgebung unterstützt auch Visual Basic und liefert einen komfortablen Editor. Leider gibt es wohl noch keinen integrierten Debugger. Man fidet die aktuellste Version unter [SharpDevelop]. Zur Unterstützung wird hier auch die Magic Library genannt, die es unter diesem [link] gibt. Aber auch diesen Weg habe ich noch nicht probieren können.
Elementare Programmierelemente und Konventionen
Wir empfehlen ein 3 schichtiges Design, d.h. für ein Plugin sollten mindestens 3 Module erstellt bzw. angepasst werden.
Daneben sollte wie in diesem Beispiel jedes Plugin ein Hilfefenster besitzen, in dem die Version, der Autor und eine kurze Beschreibung gegeben werden (frmAbout-Form).
Je nach Plugin können natürlich weitere Klassen oder Module hinzukommen, falls Sie vorhandene Controls wiederverwenden möchten.
Der GUI- Modul besteht in VB6 aus einer Form und dazugehörigem Programmcode. Man sollte darauf achten, dass in diesem Modul möglichst nur die Oberflächenaspekte implementiert werden und keine DMX-Wert-Bearbeitung. Das hat zwei Vorteile:
- man kann leichter die GUI ändern, ohne dass die DMX-Logik „Schaden nimmt“
- die separat implementierte DMX-Logik kann besser wiederverwendet werden
Der Plugin-Logik Modul befasst sich mit den Algorithmen der Verarbeitung, Analyse und Generierung von DMX-Werten. Dazu empfängt er die von DMXControl ausgegebenen DMX-Werte über interface C und manuelle DMX-Wertänderungen über Interface A. Anderererseits kann dieser Modul über Interface B Werte an DMXControl senden oder über Interface D im GUI-Modul visualisieren lassen.
Der Plugin Interface Klassenmodul hat zwei Aufgaben:
- Hier werden die call back calls von DMXControl aufgenommen und ausgewertet.
- Alle notwendigen Konfigurationswerte für die Integration des Plugins in DMXControl werden hier gesetzt, z.B. Name des Plugins oder Verhalten bei der Aktivierung.
Die Klasse DMXCPlugin_Helper liefert das Interface zum Aufruf der Kommandos durch ein Plugin. Dieses Interface ist im Anhang 1 beschrieben. Ist das Plugin aktiv, werden bestimmte Überwachungen durchgeführt ("Sicherheitsfunktionen" für plug-ins), die die Stabilität des DMXC kernels gewährleisten sollen. Insbesondere entscheidet DMXC, ob aufgrund gewisser Bedingungen bestimmte Operationen überhaupt ausgeführt werden dürfen. (Bisher noch nicht, müsste man überlegen was man sinnvoll kontrollieren kann, ohne zu viele Ressourcen zu verschwenden)
Alle Ausgabe-Plugins unterliegen einer Namenskonvention: Sie müssen mit „.out.dll“ enden. Beispiel: Dmx4All.out.dll Dies gilt nicht für Anwendungsplugins.
Plugin Interface Referenzen
Alle hier genannten Methoden gehören zur Klasse DMXCPlugin_Helper. Daher sind die folgenden Schnittstellen als Methode eines Objektes dieser Klasse aufzurufen.
Die Interfaces sind in in zwei Modulen definiert, diese müssen im Interface-Modul mit importiert werden
Implements IDMXCPlugin Implements IDMXCModule
Die benötigten Typdefinitionen befinden sich in DMXCTypeLib.dll. Daher muss dieser Modul sowohl im Programmverzeichnis von DMXControl als auch in Ihrer VB6-Umgebung bekannt gemacht werden. Dazu müssen Sie in VB6 unter dem Projektmenü den Punkt "References" aufrufen und die Verknüpfung zu DMXCTypeLib.dll herstellen. Man kann sich z.B. eine lokale Kopie im VB6-Arbeitsverzeichnis erstellen.
Public mHelper
Folgende Interfaces müssen in einem Plugin implementiert werden:
Methode | Aufgerufen von | Beschreibung | Parameter/Variable/Returnwert |
---|---|---|---|
Private Function IDMXCPlugin_Configure() As Boolean | Plugin-Konfiguration (Button "Konfigurieren") | Ruft die GUI für ggfs. erforderliche Plugin-Konfiguration | IDMXCPlugin_Configure (Boolean) teilt mit, ob ein Konfigurationsmemü existiert |
Private Function IDMXCPlugin_Enable() As Boolean | Plugin-Konfiguration/Starten aus dem Menü "Fenster" | Kann Funktionsrufe für das Aktivieren des Plugins enthalten (Aktivieren = Haken in Plugin-Liste setzen) | IDMXCPlugin_Enable (Boolean) teilt mit, ob die Operationen beim Aktivieren erfolgreich waren |
Private Function IDMXCPlugin_Disable() As Boolean | DMXControl | Kann Funktionsrufe für das Deaktivieren des Plugins enthalten (Deaktivieren = Haken in Plugin-Liste entfernen) | IDMXCPlugin_Disable (Boolean) teilt mit, ob die Operationen beim Deaktivieren erfolgreich waren |
Private Function IDMXCPlugin_Init(CallingAppTitle As String, MyFilename As String, DMXCPluginHelper As DMXCTypeLib.IPluginHelper) As Boolean | DMXControl (Laden beim Programmstart) | Kann Funktionsrufe für das Initialisieren des Plugins enthalten (Initialisieren = Laden beim Programmstart) | |
Private Function IDMXCPlugin_Term() As Boolean | DMXControl (Schließen des Plugins) | Kann Funktionsrufe für das Terminieren des Plugins enthalten (Terminieren = Schließen des Plugins) | |
Private Property Get IDMXCPlugin_PluginName() As String | Plugin-Konfiguration | übergibt der Plugin-Konfiguration den Namen des Plugins | IDMXCPlugin_PluginName (String) |
Private Property Get IDMXCModule_ModuleInfo() As DMXCTypeLib.Type_Module_Info | DMXControl beim Laden des Programms | übergibt diverse Informationen über das Plugin (siehe Tabelle unten) |
In der Methode IDMXCModule_ModuleInfo sind folgende Datenfelder anzupassen:
Attribut | Beschreibung | Kommentar/Beispiel |
---|---|---|
GUID | eindeutige ID für das Plugin | "{b61b4c42-17ed-11da-94c3-00e08161165f}" (GUID-Generator) |
Name | Bezeichnung des Plugins in Konfigurationsliste, Menübaum und Kanalübersicht (Mixerkanäle) | "Lauflicht Demo Plugin" |
Description | zusätzliche Beschreibung, z.Z. ungenutzt | "Simple GUI für Lauflichter" |
Author | Name des Programmierers, z.Z. ungenutzt | "Max Mustermann" |
Experimental | zeigt experimentellen Status im Menübaum an, falls noch nicht ausführlich getestet | True/False |
ProvidesToolWindow | gibt an, ob separates GUI-Fenster für Plugin existiert | True/False |
Category | gibt an, in welche der Kategorien des Menübaums das Plugin einsortiert wird | CAT_Control |
FormName | übergibt VB-Name des Plugin-Formulars (Oberfläche) | "frmTutorMain" |
Frm | übergibt eine Referenz auf das Plugin-Formular | Set .Frm = frmTutorMain |
ProvidesCommand | gibt an, ob Befehl für die Plugin-Funktionalität definiert wird | True |
ProvidesSceneType | gibt an, ob Plugin neuen Szenentype definiert, z.Z. noch nicht unterstützt | False |
UsesProvidedOutput | gibt an, ob Plugin Signale an den Mixer senden möchte | True |
UsesMessaging | gibt an, ob Plugin DMXControl-Messages empfangen möchte | True/False |
Messages | Collection, zu der alle zu empfangenden Messages hinzugefügt werden | Messages.Add MSG_Channel_Set |
Aus der Plugin-Anwendung können folgende Funktionen gerufen werden:
Methode | Beispiel | Beschreibung |
---|---|---|
Public Function SetChannel(Channel As Long, Value As Long, IgnoreChange As Boolean) | Call mHelper.MyStream.SetChannel(mDimmerAddr, dmxv, True) | Ausgeben eines DMX Wertes auf dem angegebenen Kanal. Der dritte Parameter gibt an, ob diese Wertänderung in der Szenenverwaltung ignoriert werden soll. |
Public Function DMXC_Channel_IsDimmer(Channel As Long) As Boolean . | Abfrage, ob der Kanal für die Helligkeit eines Gerätes zuständig ist | |
Public Property Get DMXC_CHANNEL_MAXCHANNELS() As Long | Gibt die Nummer des höchsten verwendbaren Kanals zurück | |
Public Function DMXC_Channel_GetValue(Channel As Long) As Long | dmxValue = mHelper.ChannelGetValue(currentChannel) | Hiermit kann das Plugin den aktuellen Wert abfragen. Wird z.B. bei der Plugin-Initialisierung benötigt. |
Die Interfaces werden laufend erweitert. Bitte diskutiert hier (oder schreibt uns), welche Funktionen ihr für Eure Plugins benötigt.
Plugin Interface Erweiterungen in DMXControl 2.10
In der Version 2.10 wird die Plugin-Schnittstelle um einige wesentliche Funktionen erweitert.
- Fenster-Management
- Kommandos
Fenster-Management
Für alle Plugins, die eine graphische Oberfläche haben kann zusätzlich die Schnittstelle "IExternalWindow" implementiert werden. Diese enthält Funktionen zum Fenster-Management des Plugins und ermöglicht es DMXControl den Zustand und die Position des Pluginfensters zu ermitteln, zu speichern und bei Neustart von DMXControl dieses auch direkt an der alten Position zu starten.
Im Formular des Plugins muss die Schnittstelle implementiert werden:
Implements IExternalWindow
und folgende Funktionen/Properties der Schnittstelle muss das Plugin implementieren:
Private Function IExternalWindow_showWindow() As Boolean Private Function IExternalWindow_hideWindow() As Boolean Private Function IExternalWindow_loadWindow() As Boolean Private Function IExternalWindow_unloadWindow() As Boolean Private Property Get IExternalWindow_isOpen() As Boolean Private Property Let IExternalWindow_WindowState(RHS As Long) Private Property Get IExternalWindow_WindowState() As Long
Die Bedeutung der einzelnen Elemente ist eigentlich sprechend, so dass auf eine detaillierte Beschreibung der einzelnen Funktionen hier verzichtet wird.
Kommandos
Die Verwendung von Kommandos in Plugins ist ab DMXControl 2.10 in beide Richtungen möglich. D.h., man kann im Plugin eigene Kommandos definieren, die dann in DMXControl zur Buttonbelegung, Szenendefinition, usw. auftauchen und man kann auch vom Plugin aus auf alle in DMXControl vorhandenen Kommandos zugreifen.
Definition eigener Kommandos
Um eigene Kommandos bereitzustellen, muss das Plugin die Schnittstelle ICommandServer implementieren.
implements ICommandServer
Folgende Funktionen/Properties müssen implementiert werden:
' ' mit diesem Namen taucht das Plugin in der Kommandoliste in DMXC auf ' Private Property Get ICommandServer_Name() As String
' ' hier wird auf die Kommandos reagiert Private Function ICommandServer_ExecuteCommand(FirstSelection As String, SecondSelection As String, NewValue As Long, Optional Stream As DMXCTypeLib.IDMXMixerChannel, Optional AdditionalData As PropertyBag) As Variant
' ' hier wird die erste Ebene der Kommandostruktur erstellt Private Function ICommandServer_GetFirstOptions() As DMXCTypeLib.IKeyCollection Set ICommandServer_GetFirstOptions = New KeyCollection With ICommandServer_GetFirstOptions .Add mHelper.Translator.Translate("Activate Function"), "FUNCTION" ... End With End Function
' ' hier wird die zweite Ebene der Kommandostruktur erstellt Private Function ICommandServer_GetSecondOptions(FirstSelection As String) As DMXCTypeLib.IKeyCollection Set ICommandServer_GetSecondOptions = New KeyCollection With ICommandServer_GetSecondOptions If FirstSelection = "FUNCTION" Then .Add mHelper.Translator.Translate("an"), "ON" .Add mHelper.Translator.Translate("aus"), "OFF" ElseIf FirstSelection = "LISTSELECT" Then .Add mHelper.Translator.Translate("nächster"), "NEXT" .Add mHelper.Translator.Translate("vorheriger"), "PREVIOUS" .Add "-----", "-----" .Add "1", "1" ... ElseIf FirstSelection = "VALUE" Then .Add mHelper.Translator.Translate("1. Wert"), "1.VALUE" .... End If End With End Function
Zugriff auf die Kommandos von DMXControl
Über die hier beschriebenen Methoden ist es möglich alle in DMXControl vorhandenen Kommandos zu benutzen. D.H., man kann Szenen und Effekte anwählen, starten, stoppen und vieles mehr (alles, was man auch auf einen Button legen kann). Um auf die Kommandos zugreifen zu können, braucht man ein spezielles ExtendedListView-Control für VB6. Dieses kann man aus dem Internet herunterladen (http://vcreations.net/product.asp?pid=1) und installieren. Mit den in die Plugin-Schnittstelle eingebauten Funktionen kann ein solches ExtListView gefüllt und genutzt werden.
DMXControl-Messages
DMXControl verwendet zur internen Kommunikation eine Reihe von Windows-Messages, um Vorgänge asynchron ausführen zu können. Wenn Sie ein Plugin entwickeln, ist diese Liste für sie wichtig. Jede Message hat zwei zusätzliche Datenparameter, die verschieden benutzt werden: Arg1 und Arg2. Beides sind Variablen vom Typ "Long", es können also keine Zeichenketten direkt übermittelt werden.
Bitte beachten Sie, dass Messages natürlich nur funktionieren können, wenn das entsprechende Empfänger-Fenster auch geöffnet ist.
Folgende Nachrichten sind in DMXC verfügbar:
- MSG_Channel_Set
- Der Kanal Arg1 soll auf den Wert Arg2 gesetzt werden. Diese Nachricht wird vom DMX-Mixer bei Werteänderungen erzeugt. Sie gibt nicht den endgültig auszugebeneden Wert wieder, da dieser erst noch vom Core verändert werden kann.
- MSG_Channel_Send
- Der Kanal Arg1 soll auf den Wert Arg2 gesetzt werden. Arg2 gibt den endgültigen DMX-Wert an, wie er auch zum Interface gesendet wird. Sie können diese Message verwenden, um über DMX-Werteänderungen informiert zu werden.
- MSG_Master_Set
- Der in Arg1 angegebene Fader des Masterfader-Tools wird auf den Wert Arg2 gesetzt. Dabei kann Arg1 folgende Werte annehmen:
- MST_Grand = 1
- MST_Flash = 3
- Der in Arg1 angegebene Fader des Masterfader-Tools wird auf den Wert Arg2 gesetzt. Dabei kann Arg1 folgende Werte annehmen:
- MSG_SM_Set
- Der in Arg1 angegebene Submaster (1-12) wird auf den Wert aus Arg2 gesetzt.
- MSG_SM_Move (Privat)
- Der in Arg1 angegebene Submaster (1-12) wird um den Wert aus Arg2 geändert.
- MSG_SM_Flash
- Der in Arg1 angegebene Submaster (1-12) wird geflasht (Arg2=True) oder "deflashed" (Arg2=False)
- MSG_Beat_Detected
- Eines der Sound-Tools hat einen Beat erkannt. Es ist gleichzeitig immer nur eine Beat-Quelle aktiv. Kommt der Beat vom Sound-Analyzer ist Arg1=1, kommt der Beat vom BeatTool ist Arg1=2. Arg2 wird nicht verwendet und ist immer 0.
- MSG_Command_Blackout
- Ein Blackout wird aktiviert (Arg1=True) oder deaktiviert (Arg1=False). Arg2 wird nicht ausgewertet.
- MSG_Device_Changed
- Die Gerätekonfiguration hat sich geändert. Arg1 kann das geänderte Gerät enthalten, tut dies aber nicht unter allen Umständen.
- MSG_Modules_Changed
- Die Modulkonfiguration hat sich verändert. Arg1 gibt die numerische ID des geänderten Moduls an, sollte aber nicht ausgewertet werden.
- MSG_Config_Changed
- Eine Einstellung hat sich verändert. Arg1 kann folgende Werte annehmen:
- CHG_MIDIRemote = 1
- CHG_Filename = 2
- CHG_Device = 3
- CHG_Joystick = 4
- CHG_Keyboard = 5
- CHG_DMXInRemote = 6
- CHG_ProjectFile = 7
- Beim Auftreten dieser Message mit Arg1=CHG_Filename hat der Benutzer ein anderes Projekt geöffnet. Die Tools müssen die neue Projektdatei laden.
- Eine Einstellung hat sich verändert. Arg1 kann folgende Werte annehmen:
- MSG_Config_WillChange
- Eine Einstellung wird sich ändern. Arg1 kann die gleichen Werte wie bei MSG_Config_Changed annehmen. In Verbindung mit Arg1=CHG_Filename tritt diese Message auf, wenn der Benutzer die Projektdatei wechseln möchte, aber noch bevor die Änderung aktiv wird. Daher müssen die Tools nachfragen, ob eventuelle Änderungen gespeichert werden sollen. Anschließend wird meistens MSG_Config_Changed auftreten.
- MSG_Item_Select (privat)
- Ein Element wird ausgewählt. Arg1 gibt den Elementtyp an und kann folgende Werte annehmen:
- ITM_Device = 1
- ITM_Selection = 4
- ITM_TapButton = 5
- ITM_Scenelist = 6
- ITM_SyncButton = 7
- Über Arg2 wird das Element spezifiziert. Werte größer oder gleich 0 wählen ein definiertes Element aus, folgende Werte sind ebenfalls möglich:
- SEL_Next = -1
- SEL_Prev = -2
- SEL_Act = -3
- SEL_Unselect = -4
- SEL_Next und SEL_Prev wählen das nächte bzw. vorhergehende Element aus. Sel_Act ändert die Auswahl nicht und SEL_Unselect entfernt die Auswahl des Elements.
- Ein Element wird ausgewählt. Arg1 gibt den Elementtyp an und kann folgende Werte annehmen:
- MSG_File_Save
- Der Benutzer möchte das Projekt speichern. Alle Tools speichern die aktuellen Daten in ihren Projektdateien.
- MSG_Toggle_OnOff (Privat)
- Eine Funktion soll ein- oder ausgeschaltet werden. Arg1 gibt die Funktion an und kann folgende Werte annehmen:
- TGL_Sound2Light = 1
- Arg2 bestimmt das Umschaltverhalten und kann folgende Werte annehmen:
- MDE_On = 1
- MDE_Off = 2
- MDE_Toggle = 3
- MDE_On und MDE_Off schalten die Funktion ein- bzw. aus, während MDE_Toggle den aktuellen Zustand umschaltet (On -> Off, Off -> On)
- Eine Funktion soll ein- oder ausgeschaltet werden. Arg1 gibt die Funktion an und kann folgende Werte annehmen:
- MSG_Scenelist_Go (Privat)
- Der "Go!"-Button der Szenenliste soll ausgelöst werden
- MSG_Window_View
- Die Fensteransicht wurde umgeschaltet (Edit/Execution). Arg1 kann folgende Werte annehmen:
- VIW_Execute = 1
- VIW_Edit = 2
- Die Fensteransicht wurde umgeschaltet (Edit/Execution). Arg1 kann folgende Werte annehmen:
- MSG_DMXIn_Channel_Set
- Der DMX-In-Wert für den Kanal Arg1 wurde auf den Wert Arg2 geändert.
- MSG_Item_Next (Privat)
- Der nächste Schritt eines Elements wird ausgeführt. Arg1 und Arg2 sind wie bei MSG_Item_Select belegt.