Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Organisieren von großen Programmen (https://www.delphipraxis.net/156210-organisieren-von-grossen-programmen.html)

BlueLiquidCell 23. Nov 2010 23:31

Organisieren von großen Programmen
 
Hey Guys
Habe mittlerweile ein ziemlich großes Programm geschrieben.
(ca. 20000 Zeilen)
Leider ist es mit der Übersicht bei der größe ziemlich schwierig.

Das Programm hat mehrere TabFenster. Würde gerne den Code der zu jedem Fenster gehört zusammen haben.

Kann man den jeweiligen Code irgendwie in ne externe unit schreiben?
Geht dabei um relativ viele Buttons bzw Panels auf die man klicken kann.

Klar könnte dann für jeden knopf ne function schreiben die ich aufrufe. Dann muss ich aber viel zu viele Variablen immer übergegeben etc... Gehts auch einfacher?

Hab übrigens schon da wos ging die functions in ne dll gepackt. Aber bei onClick procedures macht das keinen sinn oder?

Hoffe ihr habt nen paar ideen. Danke schonmal!

Luckie 23. Nov 2010 23:43

AW: Organisieren von großen Programmen
 
Zitat:

Zitat von BlueLiquidCell (Beitrag 1063645)
Hab übrigens schon da wos ging die functions in ne dll gepackt.

Und wie trägt das zur Übersicht im Quellcode bei? Trenne Oberfläche von den Daten und der Funktionalität.
Zitat:

Klar könnte dann für jeden knopf ne function schreiben die ich aufrufe.
Das wäre schon mal ein Ansatz. Und wenn du dann noch sauber alles in Klassen verpackst, sollt es mit der Übersicht besser werden.

BlueLiquidCell 24. Nov 2010 00:01

AW: Organisieren von großen Programmen
 
Hey
Danke für die schneller Antwort!

Naja das Programm hat noch ein Interface zu einem anderen Programm dazu müssen viele Daten in einem bestimmten format (welches ich nicht benutzen will) konvertiert werden und dann in das interface geschrieben werden. Damit der ganze code nicht im Hauptprogramm ist hab ichs in ne dll gepackt. Insofern trägts schon zur Übersicht bei.

Ok das mit den Klassen ist ne idee aber muss ich dann nicht auch alle benötigten Variablen übergeben? Sorry hab noch nicht so viel mit Klassen gemacht.

Schöne Grüße
Christoph

Bummi 24. Nov 2010 00:17

AW: Organisieren von großen Programmen
 
Ich weiß nicht ob meine Vorschlag für Dich brauchbar oder praktikabel ist.
Du könntest statt Tabs einzelne Forms erstellen, welche Du nach dem erstellen Deines Mainform per ManualDockDrop in ein leeres Tabscheet integrierst.
Du kannst dann überallhin direkt durchgreifen und hast in dem Forms den zugehörigen Code.

alzaimar 24. Nov 2010 06:37

AW: Organisieren von großen Programmen
 
Ich dachte, dazu dienen Frames...

Bummi 24. Nov 2010 07:10

AW: Organisieren von großen Programmen
 
@alzaimar

das ist eine persönliche Angelegenheit zwischen den Frames und mit.:wink:
Ich bin vor einigen Jahren von den damals fehlerhaft funktionierenden Frames auf Forms umgestiegen und war damit so zufrieden, daß ich nie wieder einen Grund sah zu wechseln.

sx2008 24. Nov 2010 07:22

AW: Organisieren von großen Programmen
 
Es ist sinnvoll, den Sourcecode in zwei Teile zu zerlegen.
* Code, der nur für diese Anwendung benötigt wird
* Code, der so allgemein ist, dass er ohne weiteres auch in einer anderen Anwendung benützt werden kann
Letzteres ist besonders wertvoll, denn einmal programmiert aber mehrfach verwendet spart Zeit.

Ein Beispiel: in einer Anwendung musst du einen String zeichenweise umdrehen.
Der erste Ansatz wäre eine Schleife an Ort und Stelle zu verwenden und die Zeichen im String umzudrehen.
Schrittweise soll das jetzt verbessert werden.
Dir wird klar, dass man den Code nicht einfach so hinklatschen darf, sondern dass man daraus eine Funktion machen muss:
Delphi-Quellcode:
// String zeichenweise umdrehen
function ReverseString(const s:string):string;
...
Bislang hast du die Funktion nur ein einziges Mal gebraucht.
Aber jetzt brauchst du sie ein zweites Mal in einer anderen Unit.
Kein Problem, einfach kopieren.
Dann kommst du drauf, das Copy & Paste Programmierung doch nicht so toll ist(genauer gesagt ist es das Dümmste was man tun kann).
Also nicht kopieren, sondern die Deklaration der Funktion in der Interface-Abschnitt der Unit A schreiben
und dann in Unit B mit Uses einbinden.
Nun brauchst du die Funktion noch ein drittes Mal in Unit C.
Aber wenn du Unit A einbindest bekommst du nicht nur die Funktion ReverseString sondern auch anderes Zeug.
Du entscheidest dich die Funktion in eine eigene Unit namens "Utilities" zu verschieben.
In dieser Unit sammeln sich im Laufe der Zeit nützliche Funktion, Proceduren und Klassen an.
Du teilst die Unit "Utilities" in mehrere Units mit unterschiedlichen Themengebieten (Stringverarbeitung, Datenbankzugriff, Verschlüsselung, ...) auf.

Zum Schluss hast du eine Bibliothek bestehend aus versch. Units, die du auch in anderen Anwendungen einbinden kannst.

himitsu 24. Nov 2010 07:54

AW: Organisieren von großen Programmen
 
Auslagern in eine DLL soll also besser sein, als ein einfaches Auslagern in verschiedene PAS?
Erhrlich gesagt, ist das sogar umständlicher, da man hier
a) schlechter Debuggen kann (da man im Allgemeinem eintweder die DLL oder die EXE debuggt)
und b) auch noch so Einiges aufpassen muß, wie Shared Memory und die getrennte RTTI, bei Verwendung von Objekten (also 'ne TStringList läßt sich nicht einfach so in beiden Teilen verwenden)

PS: Auch die kompilierten Daten werden nicht kleiner, nur weil man was in eine DLL auslagert.
Im Gegenteil, wenn man dieses nur bei einem Programm macht (also die DLLs nicht mit verschiedenen Programmen nutzt), dann werden es sogar mehr Daten.
Denn die DLL hat ja auch wieder Zusatzinfos und dann sind auch noch viele Daten doppelt (so z.B. die überall genutzten Delphi-Units, einige Resourcen usw.)

pixfreak 24. Nov 2010 08:19

AW: Organisieren von großen Programmen
 
Moin zusammen,

in meinen C Projekten habe ich genau aus Grund der Vermeidung von DLLs zwecks Auslagerung Gebrauch von statischen Libs gemacht um wiederverwendbaren Code schnell einbinden zu können.

In Delphi schiebe ich wieder zu verwendenen Quelltext, der getestet und für gut befunden wurde:wink:, in ein extra "Erweiterungsverzeichnis", welches ich im Suchpfad habe. Dann brauche ich die Unit nur einbinden und alles ist gut. DLLs etc. würde ich nur nutzen, wenn die Funktionen von mehreren Programmen gebraucht werden, oder das Programm in mehreren Instanzen ausgeführt wird. Ansonsten hat man nur Ärger. Und bei der heutigen Hauptspeichergröße ist halt sowieso die Frage was ich will: eine etwas größere exe-Datei oder den Ärger mit DLLs (am besten noch mit inkomplatiblen Schnittstellen...)

Also mein Tip: Alles was funktioniert und nicht mehr angefasst werden soll, ab in eine eigene Unit etc. Ob jetzt als Klassen (vorzuziehen, Stcihwort Vererbung und Ableitung) oder prozedural, aber dann wird das eigentliche Progamm doch wieder übersichtlicher...


Viele Grüße

Pixfreak

himitsu 24. Nov 2010 08:31

AW: Organisieren von großen Programmen
 
PS: Alles was man als mehrere Prozeduren in einer Unit hat und welches logisch zusammen gehört, das kann man auch Problemlos in eine Klasse auslagern.

Und es wirklich nur Proceduren/Funktionen sind, dann als Klassenmethoden, also mit "class function DerName" deklariert.
So muß man keine Instanz der Klasse erstellen.

Delphi-Quellcode:
Procedure MacheIrgendwasFunktionA(die Parameter);
Procedure MacheIrgendwasFunktionB(die Parameter);
Procedure MacheIrgendwasFunktionC(die Parameter);

Aufruf: MacheIrgendwasFunktionC(übergebene Parameter);

Type TMacheIrgendwas = Class
  Class Procedure FunktionA(die Parameter);
  Class Procedure FunktionB(die Parameter);
  Class Procedure FunktionC(die Parameter);
End;

Aufruf: TMacheIrgendwas.FunktionC(übergebene Parameter);
Über TMacheIrgendwas. hat man dann in der Autovervollständigung dann auch noch eine nette Übersicht der Funktionen.

Und sobald in der Unit auch noch globale Variablen auftauchen, dann gehört sowas sowieso in eine Klasse.
Entweder ebenfalls als Klassenmethoden und mit Klassenvariablen. (als "Class Var" in der Klasse deklariert),
oder eben über ein instanziertes Objekt.
Wobei Letzeres einem erlaubt, die Klasse auch mehrmals im selben Projekt zu verwenden ... Über dar Klassenmethoden/-Variablen wäre nur ein einziges "Objekt" möglich.

s.h.a.r.k 24. Nov 2010 08:34

AW: Organisieren von großen Programmen
 
Bzgl. den DLLs kann man eben argumentieren, dass man bestimmte Funktionen eben in mehreren Programmen verwenden will, somit kann man das ja in eine DLL packen -- holt sich dabei aber auch einige Probleme mit ins Boot. Ich persönlich verzichte all zu gerne drauf.

@himitsu: Ich habe das auch mit diesen tollen statischen Klassenmethoden, bin aber aufgrund des Mehraufwandes nicht wirklich begeister von dieser Lösung. 100% OOP gibts eh nicht imho.

himitsu 24. Nov 2010 08:52

AW: Organisieren von großen Programmen
 
Na gut, wenn man es gleich von Anfang an als Klassen auslegt, dann ist der Mehraufwand nicht unbedingt sooooo groß.

Und wenn man diese Klassenmethoden nicht grade statisch deklariert (mit der Aufrufkonvention "static"), dann gibt es sogar noch einen unsichtbaren internen Parameter (das liebe SELF), welcher bei jedem aufruf soeiner Methode mit übergeben wird.

Ansonsten bringt es im Quellcode auch vorwiegend nur dann mehr Übersicht, wenn man z.B. mehrere ähnliche Funktionsgruppen in einier Unit auf mehrere solcher Klassen verteilt hat.
(Bei einer einzigen Klasse, in der Unit, mag es bestimmt ein winziges Bissl mehr Aufwand sein)

PS: Seit Delphi2006/TDE nutzte ich, bei Sowas, auch gern mal Recordmethoden. :stupid:
Quasi fast das Selbe wie eine statische Klasse, welche man aber definitiv nicht instanzieren kann. (da das mit den abstracten Klassen ja nicht unbedingt gut funktionierte)

Und wenn es eine Funktion war, welche man zum Manipulieren eines Records nahm, dann ist das auch eine witzige Idee.
Denn früher mußte man den Record an die Funktion übergeben und nun ruft man die Funktion direkt über den Record auf.
(auch hier ist die Autovervollständigung wieder sehr nett, da man sich so die möglichen Funktionen zu diesem Record anzeigen lassen kann.

Ach ja, wer nun mein, daß es jetzt schwerer ist, Aufgrund der fehlenden Vererbung, dieses um Funktionen zu erweitern, der kennt die "Record Helper" noch nicht. ... Ja, das was es für Klassen (Class Helper) gibt, gibt es auch für Records.
(leider nicht für normale Typen :cry: ... TGUID hätte ich gern mal nachträglich um die zugehörigen Umwandlungsfunktionen erweitert, wie z.B. GuidToString)


PS: Diese PAS-Dateien von Delphi sind ja grade dazu da, daß man damit Alles schön aufteilen kann.
Nicht so wie in C, wo die ganze Includetechnik eigentlich das gesamte Programm nur in einer rießigen Quelltextdatei virtuellen verwaltet, wo eigentlich nichts wirklich voneinander getrennt ist (selbst wenn es in verschiedenen C- und H-Dateien drinsteht).

divBy0 24. Nov 2010 09:36

AW: Organisieren von großen Programmen
 
Was ist denn mit Packages und BPL?

himitsu 24. Nov 2010 09:44

AW: Organisieren von großen Programmen
 
Zitat:

Zitat von divBy0 (Beitrag 1063687)
Was ist denn mit Packages und BPL?

BPL ist auch "nur" eine DLL (mit speziellen Delphizusatzfeatures).
Also hier gilt das Selbe, wie bei den DLLs.
Wenn man das für nur ein Projekt macht, bringt es wohl nicht wirklich Vorteile.
Und bei Verwendung in mehreren Projekten muß man hier zusätzlich aufpassen.

PS: Die BPL muß mit dem selben Delphi-Compiler und der selben RTL/VCL-Version kompiliert sein, wie die EXE, welche sie verwenden will,
da ja die selben RTTI-Informationen verwendet werden müssen.
Dagegen ist eine "normale" DLL natürlich unabhängiger.

Wenn du also 2 Programme hast, welche die "gleiche" BPL nutzen will, aber das eine Programm noch in D2006 geschrieben ist, aber das andere Programm schon mit D2007, dann müssen auf dem Zielsystem irgendwie die BPLs für beide Delphiversionen installiert/vorhanden sein.
Und wenn das nun die einzigen Programme sind, welche diese BPLs nutzen, dann ist doch der Aufwand damit größer?

BlueLiquidCell 24. Nov 2010 13:02

AW: Organisieren von großen Programmen
 
Hey
Bei den Forms ist halt das Problem das ich die Variablen dann nur in der Form(auf der Tab seite) benutzen kann, bräuchte sie aber manchmal auch global.

Das mit den Klassen hört sich doch nach relativ viel aufwand an, vorallem weil ichs nicht von anfang an eingeplant hab ist aber wohl ne relativ gute Lösung wenn man noch länger an dem Programm arbeiten will. Muss ich mir aber erstmal genau angucken weil ich damit noch nicht wirklich was gemacht hab.

Vorteil von dlls gegenüber auslagern in ner pas ist doch dass das Hauptprogramm kleiner wird und er die dll nur läd wenn ers braucht. Oder seh ich das falsch?
StaticLibrary wär natürlich auch ne idee.
Bezüglich des debuggen hab ichs immer so gemacht das ich zunächst eine Funktion im Hauptprogramm ausprobiert hab und nachdem alles lief die funktion in die dll gepackt hab. Dann entfällt nachträgliches debuggen meistens.

Merci, für die vielen Antworten und anregungen ;-)
Christoph

Assarbad 24. Nov 2010 13:44

AW: Organisieren von großen Programmen
 
Zitat:

Zitat von himitsu (Beitrag 1063671)
Erhrlich gesagt, ist das sogar umständlicher, da man hier
a) schlechter Debuggen kann (da man im Allgemeinem eintweder die DLL oder die EXE debuggt)

Bedingtes Kompilieren? Anyone? :stupid:

joachimd 24. Nov 2010 13:54

AW: Organisieren von großen Programmen
 
Zitat:

Zitat von BlueLiquidCell (Beitrag 1063720)
Bei den Forms ist halt das Problem das ich die Variablen dann nur in der Form(auf der Tab seite) benutzen kann, bräuchte sie aber manchmal auch global.

Dann gib diese als Property in deine Form-Klasse und lese sie auch so wieder zurück. Vorteil davon: Du kannst richtig schön Formular für formular entwickeln und unabhängig(!) voneinander testen. Am Besten noch von einem gemeinsamen Vorfahren abgeleitet, damit du einzelne Methoden/Properties schonmal voraussetzen kannst (ohne tausender TypeCasts).

rweinzierl 24. Nov 2010 15:02

AW: Organisieren von großen Programmen
 
Hallo

Mein persönlicher Ansatz bei einem Formular mit vielen Pagecontrols den Code in einzelne Formulare zu trennen und diese dann ähnlich wie Frames auf dem Hauptformular zusammenzufassen.

Delphi-Quellcode:
myFrm:= TmyFrm.Create(Application);
myFrm.Position := poDefault;
myFrm.Parent := EinesDerTabsheets;
myFrm.BorderStyle := bsNone;
myFrm.Left := 0;
myFrm.top := 0;
frmVentilatorECZuluft.show;
Natürlich trennt man trotzdem Code und Darstellung, aber so habe ich nicht alles in einem Monster Formular und trotzdem für den Anwender alles schön kompakt.

mfg

Reinhold

stahli 24. Nov 2010 15:12

AW: Organisieren von großen Programmen
 
Ich hatte kürzlich hier einmal zur Zweckmäßigkeit von Frames nachgefragt und angefangen, das so umzusetzen.
Jeder dieser Frames wird nur einmal im Projekt eingesetzt und soll lediglich einer Trennung von inhaltlichen Bereichen in einzelne Units dienen.

Mich nervt dabei, dass man die Frames dann aber auch in der Mainform hat und daran (un-)absichtlich herumschrauben kann. Grundsätzlich würde ich mir wünschen, dass die IDE Frames optional nur als graues Panel darstellt und nur zur Laufzeit mit Leben füllt.

Die Idee mit eingebunden Formularen klingt aber auch gar nicht schlecht... Werde ich heute Abend mal antesten.
Welche Vorzuge gegenüber Frames kann man denn grundsätzlich nennen?

rweinzierl 24. Nov 2010 15:21

AW: Organisieren von großen Programmen
 
Vorteile:


Das Formular kann "normal" entwickelt und getestet werden, und bei bedarf auf "im Hauptformular angeklebt" abgeändert werden.

Formulare haben ein Formcreate ... (Frames glaube ich nicht)

Formulare funktionieren seit Delphi 2.0 ziemlich fehlerfrei. ( Zumindest meistens )

...

mfg

Reinhold

Bummi 24. Nov 2010 15:40

AW: Organisieren von großen Programmen
 
@stahli
Du kannst Deine Formulare, gedockt und ungedockt verwenden, Du brauchst bei u.g. Vorgehen kein Tabsheet für das Formular vorsehen, es entsteht beim docken automatisch.
Ansonsten wenn Du Dir die Properties und Events der Forms anschaust ....

Delphi-Quellcode:
    TTestsF.Create2(KundentestsF,@TestsF);
    TestsF.Show;
    TestsF.ManualDock(KundentestsF.PC,nil,alnone);
wie Eingangs in diesem Thread erwähnt ist dies die seit 10 Jahren bei mir bevorzugte Methode.

Assarbad 24. Nov 2010 16:30

AW: Organisieren von großen Programmen
 
Übrigens, was hier in diesem Thema angesprochen wird, ist genau das was ich immer so erkläre: Delphi und CB verleiten zu schlampigem Programmieren.

Auch wenn es Delphianer ungern hören, wenn man in Delphi mit Forms usw. programmiert muß man unheimlich diszipliniert sein um nicht in den Spaghetticode abzugleiten zu dem einen die IDE verleitet. Wer schonmal solchen Code warten durfte (und ihn vorher nicht selber verbrochen hatte), der wird mir unumwunden zustimmen.

Was ich damit meine ist u.a., daß man nicht einfach "drauf los" programmieren und die Ereignisbehandlungsroutinen direkt bestücken sollte, sondern lieber die Logik auslagern und von der GUI trennen sollte (was ja hier vorher schon angesprochen wurde).

(C# mit WinForms ist in der Hinsicht übrigens ähnlich)

mquadrat 24. Nov 2010 17:11

AW: Organisieren von großen Programmen
 
@Assarbad

Das ist doch überall so ähnlich. Delphi DFM + PAS entspricht ja in etwa auch WPF XAML + Code Behind.


@Aufteilen in mehrere BPLs / DLLs

Das steht bei mir demnächst auch an, funktoniert aber nur dann halbwegs schermzfrei wenn alles lose gekoppelt ist. Nebenfrage: Ist eigentlich Code Insight schneller, wenn man den Code aufteilt oder wird doch wieder alles compiliert? Das nervt mich aktuell am meisten, IMHO wird da viel zu oft viel zu viel compiliert. Mir würde es vollkommen langen den letzten Compilierungs-Stand (manuelles Compilieren) im Code-Insight zu haben. Aber gut jetzt wird's dann doch Off-Topic.


@Frames

Frames sind irgendwie nichts halbes und nichts ganzes. Eine Black-Box wäre mir da mitunter wirklich lieber. Um Frames auch als Formular aufrufen zu können, hab ich mir immer einfach ein Wrapper-Formular geschrieben, in das man eben den Frame injecten konnte.

Assarbad 24. Nov 2010 18:14

AW: Organisieren von großen Programmen
 
Zitat:

Zitat von mquadrat (Beitrag 1063782)
Das ist doch überall so ähnlich. Delphi DFM + PAS entspricht ja in etwa auch WPF XAML + Code Behind.

WPF ist für mich auch nur WinForms weitergedacht :stupid:

Einerlei. Das war auch nicht was ich meinte. Delphi und CB verleiten dazu den Code gleich in die Ereignisbehandlungsroutine zu klimpern, was man aber tunlichst vermeiden sollte, wenn man Logik und Präsentation auch nur ansatzweise trennen will. Die meisten Codebeispiele zeigen aber leider genau diesen Stil. Und erfahrungsgemäß überwiegt er auch. Keine Ahnung was man an Delphi ändern könnte um das zu entschärfen, aber ich sehe das als eines der Probleme (neben dem Hersteller :zwinker:).

nachti1505 24. Nov 2010 20:27

AW: Organisieren von großen Programmen
 
Zitat:

Zitat von sx2008 (Beitrag 1063662)
Du teilst die Unit "Utilities" in mehrere Units mit unterschiedlichen Themengebieten (Stringverarbeitung, Datenbankzugriff, Verschlüsselung, ...) auf.
Zum Schluss hast du eine Bibliothek bestehend aus versch. Units, die du auch in anderen Anwendungen einbinden kannst.

Ich nehme an, diese Unit binde ich dann nur per uses ein, oder? Was wäre denn der Unterschied zum Hinzufügen zum Projekt? Bzw. was ist generell der Unterschied zwischen uses und einbinden?

Assarbad 24. Nov 2010 20:31

AW: Organisieren von großen Programmen
 
Zitat:

Zitat von nachti1505 (Beitrag 1063820)
Ich nehme an, diese Unit binde ich dann nur per uses ein, oder? Was wäre denn der Unterschied zum Hinzufügen zum Projekt? Bzw. was ist generell der Unterschied zwischen uses und einbinden?

Ich sehe da keinen Unterschied. Dem Linker mußt du doch trotzdem noch sagen was er zusammenlinken soll. Also irgendein Teil deines Codes wird wohl zwangsläufig die Unit per uses einbinden (bspw. von der .dpr aus).

mquadrat 25. Nov 2010 09:33

AW: Organisieren von großen Programmen
 
Zitat:

Zitat von Assarbad (Beitrag 1063796)
Das war auch nicht was ich meinte. Delphi und CB verleiten dazu den Code gleich in die Ereignisbehandlungsroutine zu klimpern, was man aber tunlichst vermeiden sollte, wenn man Logik und Präsentation auch nur ansatzweise trennen will. Die meisten Codebeispiele zeigen aber leider genau diesen Stil. Und erfahrungsgemäß überwiegt er auch. Keine Ahnung was man an Delphi ändern könnte um das zu entschärfen, aber ich sehe das als eines der Probleme (neben dem Hersteller :zwinker:).

Jep interessanterweise mache ich das selber in Delphi auch oft so, während ich unter .NET nicht den Drang verspüre. Aber dort benutze ich auch ein MVVM Framework. Ich denke mal ein Problem ist das becheidene Databinding in Delphi. Man muss dauernd Glue-Code schreiben. Und wenn da schon Code drin steht, dann schreibt man eben nochmal was dazu. Ist ja nur eine Kleinigkeit. Und noch eine Kleinigkeit. Und noch eine.

Oder es liegt daran, dass das .DFM versteckt wird und es daher gar nicht so den Eindruck macht, man würde jetzt im Formular arbeiten.

Oder es liegt daran, dass bei Delphi gesagt wird "blöd" wenn man Code im Formular hat, während man von der .NET Gemeinde erschossen, ertränkt und danach viergeteilt wird. Allein schon wenn man wagt nachzufragen ob ein MVVM denn immer Sinn macht ;)

Aber jetzt wird's OT. Sorry.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz