Tutorials
Andorra 2D Windowframeworks
Einleitung
Bisher haben wir als Basis unserer Andorra 2D-Anwendung immer die VCL verwendet. Doch zugegebnermaßen bringt uns dies nicht sonderlich viel. Schließlich verwendeten wir die VCL nur zum erzeugen eines Fensters und zum Verknüpfen der Events - das können wir auch ohne VCL und das ohne viel mehr Aufwand. In diesem Tutorial wird Ihnen erklärt, wie die "Andorra 2D Windowframeworks" funktionieren und wie Sie diese effektiv nutzen.
Was ist ein Andorra 2D "Windowframework"?
Allgemeines
Bevor wir über die "Windowframeworks" reden, sollten wir uns erst einmal darüber aufklären, was dieses eigentlich ist.
Abstrakt gesprochen, handelt es sich bei einem Andorra 2D Windowframework um eine Klasse, welche Funktionen zum erstellen eines Fenster bzw. zum Binden an ein bereits bestehendes Fenster zur Verfügung stellt, sowie Ereignisse verwaltet. Durch Verwendung der Andorra 2D Windowframeworks haben sie Zugriff auf eine weitere Abstraktionsebene von Andorra 2D, die es ermöglicht die Fenster- und Ereignisverwaltung komplett unabhängig von einem Fenstersystem durchzuführen.
Die Andorra 2D Windowframework-Klasse besitzt im wesentlichen zwei Methoden:
Als erstes wäre da die "BindTo"-Funktion zu nennen, welche einen beliebigen Pointer auf ein beliebiges, schon existierendes Fenster/eine schon existierende Komponente annimmt. Wir müssen hierbei zwischen zwei Arten von Windowframeworks unterscheiden: Diejenigen, die selbst ein Fenster erstellen und diejenigen, die es ermöglichen auf ein bestehendes Fenster zuzugreifen.
Wenn die Anbindung erfolgreich war, kann die "Initialize"-Funktion aufgerufen werden, welches schließlich das Fenster initialisiert. Hier werden außerdem noch die Darstellungseinstellungen übergeben. Aktuell werden diese bei einem Windowframework, welches nicht selbst ein Fenster erstellt, ignoriert.
Hierbei wird zurückgegeben, ob die Erstellung des Fensters geglückt ist.
Suchen nach Windowframeworks
Bei der praktischen Verwendung der Windowframeworks müssen wir uns um die oben genannten Methoden eigentlich nicht kümmern, da sich die Klasse "TAdDraw" automatisch um deren ansprechen. Und so geht "TAdDraw" vor:
- Alle eingebundenen Windowframework-Bibliotheken registrieren sich direkt nach dem Programmstart
- Beim Aufrufen von "TAdDraw.Initialize" geht dieses alle verfügbaren Windowframeworks durch und unternimmt die folgenden Schritte:
- Ruft die "BindTo" Funktion jedes Windowframeworks mit dem in "TAdDraw.Create" angegebenen "Parent" Parameter auf
- Gibt die Funktion "true" zurück (hat also Erfolg), so wird die Klassenhirachie der Windowframeworkklasse als String an die ausgewählte Grafikplugin-Bibliothek übergeben
- Berichtet diese, dass sie mit dem Windowframework kompatibel ist, so wird die Klasse ausgewählt und die Suche erfolgreich abgebrochen
- Ist kein Windowframework vorhanden, welches die beiden Tests besteht, so kann Andorra 2D nicht initialisiert werden
- Ruft die "BindTo" Funktion jedes Windowframeworks mit dem in "TAdDraw.Create" angegebenen "Parent" Parameter auf
- Nun wird von dem ausgewählten Windowframework die "InitDisplay"-Funktion aufgerufen und das Windowframework an die Grafikplugin-Bibliothek übergeben
Die folgende Abbildung illustriert das Suchen nach einem kompatiblem Windowframework noch einmal:
Aus diesem Prozedere ergibt sich für den Benutzer folgende, einfache Verwendungsmöglichkeit der Windowframeworks: Alle Units der Windowframeworks, die verwendet werden sollen, werden einfach in die "uses"-Anweisung in unserem Projekt geschrieben. Durch die automatische Registrierung beim Programmstart, wird unter diesen nach einem Framework gesucht, welches sowohl mit dem Zielfenster als auch dem Plugin kompatibel ist.
Um Kompatibilität zu "alten" Andorra 2D-Anwendungen zu halten, ist standardmäßig eine Windowframeworkunit eingebunden, welche als Target Window ein bestehendes VCL/LCL Fenster annimmt.
Da die Verwendung der VCL/LCL bekanntlich die ausführbare Datei unnötig aufbläht und dies durch die Verwendung entsprechender, neuer, Windowframeworks nicht unbedingt mehr nötig ist, kann das Einbinden des Standardframeworks durch das Definieren eines einfachen Kompilerschalters verhindert werden. Unter Delphi ist dies über "Projekt->Optionen->Verzeichnisse/Bedingungen" möglich. Der Name des Kompilerschalters lautet:
Sie müssen das Projekt nach der Definition komplett neu erzeugen (SHIFT+STRG+F9).
Verfügbare Windowframeworks
Nachfolgend eine kurze Auflistung aller Windowframework-Units:
- AdWin32Window - Wie der Name schon sagt ein Windowframework, welches nur unter Windows (und nur mit Delphi) funktioniert. Es steuert direkt die Windows API an um ein Fenster zu erzeugen.
- AdGLFWWindow - Ein Windowframework, welches die Bibliothek GLFW verwendet um einen Context samt Fenster zu erzeugen.
- AdStdWindow - Verwendet die VCL/LCL um ein Fenster zu erzeugen.
- AdComponentWindow - Ein Windowframework, welches es ermöglicht ein Windowframework direkt auf einer bestehenden Komponente einer VCL/LCL Anwendung zu erstellen. Dieses Framework ist standardmäßig eingebunden. Wie Sie das Einbinden dieser Unit verhindern können, lesen Sie oben nach.
Die letzten beiden Windowframework-Units kümmern sich selbst um das einbinden entsprechender Units, welche an den Verwendeten Compiler bzw. das verwendete Betriebssystem angepasst sind.
Über zwei Klassen
Die Windowframeworks wurden Ursprünglich eingeführt um den Linuxsupport zu ermöglichen.
Unter Windows konnte Andorra 2D der Pluginbibliothek einfach ein Handle auf ein bereits bestehendes Windows-Fenster übergeben. Danach kümmert sich das Plugin selbst um die Erzeugung des entsprechenden Devicecontexts. Unter Linux ist dies jedoch nicht ohne weiteres möglich: Für jedes Fenstersystem müsste eigener Code zur Contexterzeugung mitgebracht werden.
Damit nicht jeder Linuxprogrammierer bei Null starten muss, gibt es eine Reihe von Plattformunabhängigen Bibliotheken, welche sich um das Erzeugen eines Fensters und dem dazugehörigen Context kümmern. Die Frage war, wie man diese Bibliotheken nun so kapseln kann, dass Sie in das Konzept von Andorra 2D passen. Das so entstandene Windowframework-System bietet also:
- Nach wie vor die Unterstützung von mehreren Grafikplugins
- Für den einfachen Benutzer keine (oder kaum) sichtbare Änderungen. Andorra 2D soll sich nach dem gleichen Schema wie zuvor verwenden lassen
- Die Events des erstellten Fensters müssen sich in der Andorra 2D Anwendung verwenden lassen
- Komplette Trennung des Fenstersystems und dem restlichen Andorra 2D
Wir unterscheiden nun grundlegend zwei Basiswindowframeworkklassen:
- TAdHandleWindowFramework - Nur unter Windows lauffähig
- TAdGLContextGeneratingWindowFramework - Nur mit dem OpenGL-Plugin lauffähig
Ein "TAdHandleWindowFramework" besitzt ein Handle, welches von einem beliebigen Grafikplugin (unter Windows) zur Contexterzeugung verwendet werden kann. Das "TAdGLContextGeneratingWindowFramework" erzeugt hingegen in der Hostanwendung schon ein OpenGL-Context, sodass das Grafikplugin nur noch drauf los zeichnen muss.
Unsere VCL/LCL unabhängige Anwendung
In diesem Kaptiel möchten wir nun endlich eine Anwendung erstellen, die die Andorra 2D Windowframeworks ausnutzt und Plattformunabhängig kompilierbar ist. Bitte beachte Sie, dass es sich bei unserem Beispiel nur um einen Vorschlag handelt, den Sie getrost weiter ausbauen können.
Wir erstellen zunächst in der Entwicklungsumgebung ihrer Wahl eine leere Konsolenanwendung, bzw. ein leeres Programm ohne Formulare. Wir fügen eine neue Unit mit dem Namen "Main.pas" zu dem Projekt hinzu. In dieser Deklarieren wir ein neues Objekt namens "TAdAppl":
TAdAppl = class
public
procedure Run;
end;
In der Haupanwendungsdatei (also der *.lpr/*.dpr) fügen wir folgenden Code ein:
Appl:TAdAppl;
begin
Appl := TAdAppl.Create;
try
Appl.Run;
finally
Appl.Free;
end;
end.
Nun kommen wir zur Implementierung unserer "TAdAppl.Run"-Methode. Dazu binden wir uns in "Main.pas" die zugehörigen Andorra 2D-Units ein:
AdClasses, AdEvents, AdTypes, AdDraws, AdStdWindow, AdDLLExplorer;
Wie weiter Oben beschrieben deklarieren wir den Kompilerschalter
damit wir später auf die VCL/LCL verzichten können.
Die Implementierung von "Run" sieht nun folgendermaßen aus:
var
AdDLLExplorer: TAdDLLExplorer;
begin
AdDraw := TAdDraw.Create(nil);
AdDraw.DllName := DefaultPlugin; //Function in the AdDLLExplorer unit
AdDraw.Display.Width := 800;
AdDraw.Display.Height := 600;
AdDraw.Display.BitCount := 32;
if AdDraw.Initialize then
begin
AdDraw.Window.Title := 'Andorra 2D';
AdDraw.Run;
end;
AdDraw.Free;
end;
Anstatt der vielen Kompilerschalter können wir auch die Klasse "TAdDllExplorer" aus der Unit "AdDllExplorer" verwenden, die nach Andorra DLLs in dem Anwendungsverzeichnis sucht.
Ein Druck auf F9 sollte uns (nach der Deklaration der Variable "AdDraw") ein leeres Fenster mit dem Titel "Andorra 2D" beschehren. Nun müssen wir nur noch einige Events verknüpfen, dann sind wir schon am Ziel angelangt.
Nachdem "TAdDraw" ein kompatibles Windowframework gefunden hat, können wir auf dieses über die "Window"-Property zugreifen. Über
erhalten wir auf die Ereignisse des Windowframeworks Zugriff. Wir deklarieren nun eine Methode
in unserer "TAdAppl"-Klasse und verknüpfen diese über
mit den Ereignissen. In Idle können wir nun, wie wir es gewohnt sind unseren Andorra 2D-Zeichencode ablegen.
Ab diesem Punkt unterscheidet sich das Programmieren ohne VCL/LCL nicht mehr viel von dem Programmieren damit. Der einzige Unterschied beruht darauf, dass wir die Events "per Hand" verknüpfen müssen.
Indem wir in der "uses" Anweisung "AdStdWindow" durch eine der anderen Windowframeworkunits ersezten, läuft unsere Anwendung beim nächsten Start mit diesem. Wie oben beschrieben, können Sie auch mehrere Windowframeworkunits einbinden. Diese werden in der Reihenfolge ihres Auftretens abgearbeitet. Bindet man also
ein, so wird das GLFW-Framework nur bei der Verwendung eines "OpenGL-Plugins" engesetzt, bei dem DirectX-Plugin hingegen das "AdWin32Window".
Bitte beachten Sie, dass das GLFW-Framework die GLFW-Bibliothek sowie den Pascal-Header dafür benötigt. Beides befindet sich im Prerequisiten-Package von Andorra 2D.
Copyright und Lizenz
(c) by Andreas Stöckel Februar 2008
Der Inhalt dieses Tutorials steht unter der GNU Lizenz für freie Dokumentation.
This page was generated with the help of the following PHP-Scripts: GeSHi a free PHP Syntax highlighter and StringParser_BBCode a free BBCode Parser.