Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Buttonabhängiges Schließen des Programms (https://www.delphipraxis.net/155352-buttonabhaengiges-schliessen-des-programms.html)

hans ditter 20. Okt 2010 01:25

Buttonabhängiges Schließen des Programms
 
Hi DPler,
ich habe mich jetzt schon zum zweiten Mal gefragt, wie man das schließen einer Anwendung abhängig davon machen kann, welcher Button gedrückt wird.
Konkret geht es darum, dass ich gerade ein Chat schreibe. Nun wollte ich am Anfang ein Anmeldefenster einfügen. Wenn man das Programm startet, dann sieht man im Hintergrund das eigentliche Chatfenster (ist nicht enabled). Davor ist eine kleiner Fenster zu sehen, in welchem man Benutzername und Passwort eingibt, dann auf Anmelden klickt.
Beim Klick auf den Button Anmelden soll nur dieses Fenster geschlossen werden. Wenn man aber auf das rote Kreuz oben in der Ecke des Fenster klickt, soll das Programm beendet werden.

Hoffe ihr könnt nachvollziehen, wo mein Problem liegt. Ich habe mir auch schonmal OnCloseQuery angeschaut, aber das passt auch nicht auf mein Problem. Denn das Anmeldefenster soll ja in jedem Fall geschlossen werden, nur die Behandlung des Hauptfensters soll ja abhängig von dem gedrückten Button sein.

LG, hans ditter

Medium 20. Okt 2010 02:09

AW: Buttonabhängiges Schließen des Programms
 
Guck dir mal TForm.ShowModal und TForm.ModalResult an, bzw. auch TButton.ModalResult. (Tipp: Schließen über das rote X dürfte "mrNone" liefern.)

hans ditter 20. Okt 2010 02:58

AW: Buttonabhängiges Schließen des Programms
 
Hey, danke für die Antwort. Werds mir morgen mal anschauen... bin jetzt echt müde... :|:vernupft::corky::drunken: :pale: :freak:

(Ok, ich geb zu, hab's grad ein biiischen übertrieben mit den Smileys.... :D und schon wieder einer, ein Teufelkreis ... :lol: :firejump:)

youuu 20. Okt 2010 07:08

AW: Buttonabhängiges Schließen des Programms
 
Zitat:

Zitat von Medium (Beitrag 1056612)
Guck dir mal TForm.ShowModal und TForm.ModalResult an, bzw. auch TButton.ModalResult. (Tipp: Schließen über das rote X dürfte "mrNone" liefern.)

Plediere ebenfalls für Showmodal.

Siehe Quelltext für Anwendung:

Delphi-Quellcode:
begin
  Application.Initialize;
  Application.MainFormOnTaskBar:= true;

  frm_Login:= Tfrm_Login.Create(nil);
  try
    if frm_Login.ShowModal = mrOk then
      Application.CreateForm(Tfrm_Start, frm_Start);
  finally
    frm_Login.Free;
  end;
  Application.Run;
end.
So wird erst dein Chatfenster erstellt, wenn dein Login ein mrOk liefert, falls es das nicht tut und wird beendet, schließt sich die komplette Anwendung.

hans ditter 20. Okt 2010 13:03

AW: Buttonabhängiges Schließen des Programms
 
hm, werds gleich nochmal googlen, aber könntest du an meinem Quelltext nochmal die Änderungen, die ich vornehmen muss mit Kommentaren posten?
Hier mein Quelltext:
Delphi-Quellcode:
program Client;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form4},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

DeddyH 20. Okt 2010 13:56

AW: Buttonabhängiges Schließen des Programms
 
Welches ist denn das LoginForm?

hans ditter 20. Okt 2010 15:30

AW: Buttonabhängiges Schließen des Programms
 
Form1 --> Hauptform
Form2 --> Loginform
Beide Forms werden (eigentlich) bei Programmstart erstellt.

Ich hatte mir zu Hause auch Gedanken gemacht. Das ist rausgekommen:
Delphi-Quellcode:
program Client;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form4},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  //Application.MainFormOnTaskBar:=True; --> failure: Application kennt diesen Bezeichner nicht
  Form2:=TForm2.Create(nil);
  try
    if Form2.ShowModal = mrOk then
      Application.CreateForm(TForm1,Form1);
  finally
      Form1.Free;
  end;
  Application.Run;
end.
Der restliche Quelltext funzt auch nicht. Da wird das Loginfenster halbwegs erzeugt, dann kommt aber eine Fehlermeldung, dass aus einem sichtbaren Fenster kein modales gemacht werden kann.

DeddyH 20. Okt 2010 15:38

AW: Buttonabhängiges Schließen des Programms
 
Ungetestet:
Delphi-Quellcode:
program Client;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form4},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Form2:=TForm2.Create(nil);
  try
    Form2.Visible := false;
    if Form2.ShowModal = mrOk then
      Application.CreateForm(TForm1,Form1);
  finally
      Form2.Free; //Form2, nicht Form1
  end;
  Application.Run;
end.

hans ditter 20. Okt 2010 15:49

AW: Buttonabhängiges Schließen des Programms
 
tja, das funktioniert schonmal fast super.
Ich hatte versehentlich eingegeben
Delphi-Quellcode:
if Form2.ShowModal <> 0 then
... und was soll ich sagen, dass funktioniert. Wenn ich da angebe
Delphi-Quellcode:
if Form2.ShowModal = mrOk then
erzählt er mir, dass 'mrOk' ein 'undefinierter Bezeichner' ist.

Und dann hab ich noch eine Verständnisfrage. Du erzeugst Form2. Machst es dann aber unsichtbar, man kann es aber trotzdem sehen? Ist mir im Moment noch ein Rätsel... :glaskugel:

DeddyH 20. Okt 2010 16:25

AW: Buttonabhängiges Schließen des Programms
 
Ein kurzer Blick in die Referenz:
Zitat:

Zitat von Delphi-Referenz
constant Controls.mrOk

Aha, Controls fehlt in der uses-Klausel ;) Und Formulare sind per Default erst einmal nicht visible, das hast Du anscheinend im OI geändert. Also setze ich das wieder zurück, um die Fehlermeldung abzustellen.

hans ditter 20. Okt 2010 16:34

AW: Buttonabhängiges Schließen des Programms
 
Danke! Funktioniert jetzt.
Wenn ich das jetzt als Login-Fenster nehmen will, dann hab ich mir das so gedacht, dass man eben seinen Benutzernamen und Passwort eingibt. Diese werden als 'Nachricht' an den Server geschickt, der überprüft, ob die Zugangsdaten korrekt sind und schickt eine Nachricht zurück, die dann das Schließen des Fensters regelt.
Wenn alles korrekt war, dann eben das, was man mir hier freundlicherweise gezeigt hat. Wenn die Daten aber nicht stimmen, dann soll das Fenster geöffnet bleiben, möglicherweise auch eine Fehlermeldung kommen.

ABER: Wie realisier ich das jetzt?

lg, hans ditter

DeddyH 20. Okt 2010 16:42

AW: Buttonabhängiges Schließen des Programms
 
Das dürfte mit dem jetzigen Lösungsweg schwierig bzw. sehr umständlich werden. Nur so als Gedankengang:
-die Client-/Server-Funktionalität in eine eigene Unit (z.B. ein Datenmodul) auslagern
-das LoginForm zum Hauptformular machen
-nach erfolgreichem Login verstecken, Form1 erzeugen und anzeigen
-um die Anwendung zu beenden, dann eben das versteckte MainForm (also Form2) schließen

Bummi 20. Okt 2010 22:03

AW: Buttonabhängiges Schließen des Programms
 
Warum nicht im Constructor des Mainforms den Logindialog öffnen , wenn hier nicht erfolgreich abgearbeitet wird , Meldung anzeigen und ein Terminateflag setzen welches die Anwendung beendet.

hans ditter 21. Okt 2010 13:32

AW: Buttonabhängiges Schließen des Programms
 
@ Bummi ... äääääh, weil ich das nicht kann?!:cry:
@ daddyH Ja, ok... ich versteh nicht ganz was du meinst mit
Zitat:

die Client-/Server-Funktionalität in eine eigene Unit (z.B. ein Datenmodul) auslagern
... sowas hab ich noch nie gemacht... :pale::|

DeddyH 21. Okt 2010 13:43

AW: Buttonabhängiges Schließen des Programms
 
Ich vermute, dass Du die Socket- (oder Indy, oder welche auch immer) Komponenten auf Form1 hast. Diese kannst Du in ein TDataModule packen und dann von beiden Units darauf zugreifen.

youuu 21. Okt 2010 14:28

AW: Buttonabhängiges Schließen des Programms
 
Sorry hatte etwas wenig Zeit gehabt, aber DeddyH hat es dir ja erklärt gehabt.

Ich zeig dir mal wie ich mein Login Form benutze:

Delphi-Quellcode:
  Try
    QueryLogin.SQL.Text:='Select * from `Table` WHERE username LIKE EINGABE;';
    QueryLogin.Open;

    if QueryLogin.FieldByName('pw').AsString = md5string(EditPasswort.Text) then // PW ist in MD5 gespeichert
      ModalResult:= mrOk
    Else
      Showmessage('Benutzername und Passwort stimmen nicht überein.');
  Finally
    QueryLogin.Close;            // Schließe Query zum schluss
    QueryLogin.Free;
  End;
Exception Behandlung habe ich mal weg gelassen.

hans ditter 22. Okt 2010 23:26

AW: Buttonabhängiges Schließen des Programms
 
Liste der Anhänge anzeigen (Anzahl: 1)
Aaaaaaaarggggghhhhhhhhhhhh!!!!!!!!!!!!!!!!!!!!:evi l::evil::x:x:x:x:x:x:wall::wall::wall::wall::wall: :wall::wall::wall::kotz: :kotz: :kotz: :kotz: :kotz: :kotz: :kotz:

Jetzt hab ich gerade versucht umzusetzen, was DeddyH gesagt hat... und rausgekommen ist nur, dass mein Chat jetzt wieder Macken hat!!! :kotz::wall:

Das mit dem Datenmodul hat leider gar nicht geklappt. Das hab ich jetzt auch mal eben schnell wieder gelöscht, aber jetzt funktionieren auch andere Sachen wieder nicht mehr.

Wenn mein Server jetzt nicht online ist, dann bekomme ich so ein **** PopUp-Fenster, dass mir sagt, das ein "Asynchroner Socket Fehler 10061" vorliegt. Mir ist klar, dass das der Fehler ist, wenn der Client den Server nicht erreichen kann, aber ich will dieses blöde Fenster nicht :wall:!

Dabei gibt es eigentlich eine Routine, die das verhindern soll.

Und jetzt stell ich gerade fest, dass das Programm gar nicht mehr kompiliert werden kann!! :wall::wall::wall::wall::wall::wall::wall::wall::w all::wall::wall::wall::wall::wall::wall::wall:
:wall::wall::kotz::kotz::kotz::kotz::kotz::kotz::k otz::kotz::kotz::kotz::kotz::kotz::kotz::kotz:
:kotz::kotz:

Entschuldigt bitte meinen emotionalen Ausbruch, aber manchmal geht mir das tierisch auf den ****!

Hoffe ihr könnt mir nochmal helfen.
Ich hab den kompletten Quelltext nochmal angehängt.

LG, hans ditter

Luckie 22. Okt 2010 23:30

AW: Buttonabhängiges Schließen des Programms
 
Dann behandele die Exception halt.

Sir Rufo 22. Okt 2010 23:48

AW: Buttonabhängiges Schließen des Programms
 
Und benutze ein VersionsSystem Ala SVN (so was geht auch ohne Server), dann könntest du jetzt einfach wieder zurückstellen

hans ditter 23. Okt 2010 14:38

AW: Buttonabhängiges Schließen des Programms
 
@ Lucki: Das ist ja das Merkwürdige. Es gibt ja eine Fehlerbehandlung. Bei OnClientError (oder so ähnlich heisst das ja) wird ja auf jeden Fehler reagiert und der Fehlercode auf '0' gestellt, damit kein Fenster aufpoppt.
Aber irgendwie funktioniert das nicht mehr.

@ DeddyH: Vielleicht könntest du nochmal für Deppen erklären, wie das funktionieren soll. (Wie du diese Unit machst / wie du auf die Komponenten dann zugreifst)

[OFFTOPIC] @SirRufo: Da du das ansprichtst. Könntest du da mal ein paar Links posten, oder Stichwörter nach denen ich suchen kann? [/OFFTOPIC]

hans ditter 23. Okt 2010 14:46

AW: Buttonabhängiges Schließen des Programms
 
Also, ich hab das Probelm mit den Fehlern wieder hinbekommen. Aus irgendeinem kühlen Grund, bestand die Zuweisung der Ereignisroutine zu dem ClientSocket nicht mehr. Konnte ich wieder durch Dplklicken im OI herstellen. Das funktioniert wieder! :) Tut mir nochmal Leid für meinen Wutanfall... :oops:

@DeddyH: Vielleicht könntest du trotzdem mal posten, wie genau man das jetzt macht, ohne das Programm neu zu schreiben.

Vielen Dank!
hans ditter

Sir Rufo 23. Okt 2010 14:57

AW: Buttonabhängiges Schließen des Programms
 
Bei Google suchenTortoiseSVN Bei Google suchenTortoiseHg

DeddyH 24. Okt 2010 11:58

AW: Buttonabhängiges Schließen des Programms
 
Und zum Datenmodul: das kann ich auch nicht besser beschreiben als die Hilfe selbst: http://docwiki.embarcadero.com/VCL/d...es.TDataModule

hans ditter 25. Okt 2010 17:56

AW: Buttonabhängiges Schließen des Programms
 
Wow, cool! Das hat funktioniert! Danke für den Link! Sollte häufiger mal auf diese Seite schauen... :oops:
Mir ist aber aufgefallen, dass man immer
Code:
Unit3.DataModule3.{...}
schreiben muss, um auf Komponenten zugreifen zu können. Geht das nicht einfacher? Das man irgendwie definieren kann, dass
Delphi-Quellcode:
var Unit3.DataModule3: DataModule;
ist?

Das wär noch ganz nett, aber erstmal vielen Dank dafür soweit!

hans ditter

DeddyH 25. Okt 2010 18:23

AW: Buttonabhängiges Schließen des Programms
 
Es steht Dir doch frei, eine entsprechende Variable zu deklarieren und zu belegen.

hans ditter 26. Okt 2010 19:48

AW: Buttonabhängiges Schließen des Programms
 
Ja, das dachte ich auch. Ich poste mal den Anfang vom Quellcode...
Delphi-Quellcode:
unit Unit1;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, ComCtrls, StrUtils, superobject, ExtCtrls;

const
  MY_PORT = 30000; // an diesem Port wartet der Server auf Clients

type
  TForm1 = class(TForm)
    ServerAdress: TEdit;
    Online: TCheckBox;
    Input: TEdit;
    BtnSend: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    log: TRichEdit;
    lstUsers: TListBox;
    edtOwnUserNick: TEdit;
    Shape1: TShape;
    Shape2: TShape;
    Shape3: TShape;
    combContentSize: TComboBox;
    combContentColor: TComboBox;
    combContentStyle: TComboBox;
    ClientSocket: TClientSocket;
    procedure FormCreate(Sender: TObject);
    procedure OnlineClick(Sender: TObject);
    procedure BtnSendClick(Sender: TObject);
    procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure FormDestroy(Sender: TObject);
    procedure InputKeyPress(Sender: TObject; var Key: Char);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

uses Unit3;

var
  DataModule: Unit3.TDataModule3;
Während der Entwicklungszeit geht das auch alles ohne Fehler. Der Fehler tritt aber auf, wenn
Delphi-Quellcode:
DataModule.ClientSocket.Port:=MY_PORT;
aufgerufen wird.
Dann sagt er, dass eine EAccessViolation aufgetreten ist. Wie hab ich das dann denn zu verstehen?

lg, hans ditter

hans ditter 26. Okt 2010 20:19

AW: Buttonabhängiges Schließen des Programms
 
Ok, Problem hat sich gerade erledigt. Es reicht wenn ich DataModule3.{...} schreibe. Das reicht mir, ist kurz genug... ;)
Zur Funktion hab ich noch eine Frage. Ich möchte ja ein Anmeldefenster anzeigen lassen, in dem man Nick und Passwort eingibt. Wenn diese vom Server authentifiziert werden, dann soll ja die Form1 aufgerufen werden. Vom Prinzip kein Problem, aber wenn der Client sich mit dem Server connected hat, wird (im Moment noch) im Verlaufsfenster (des noch nicht erzeugten Form1) einige Informationen angezeigt. Da kommte natürlich eine Fehlermeldung, dass ein AccessFehler aufgetreten ist.
Doch wie umgehe ich das? Ich dachte schon einen zweiten Clienten dynamisch erzeugen, der nur dafür da ist, die Authentifizierung vorzunehmen, find ich persöhnlich aber nicht so schick.
Habt ihr noch andere Ideen? (Habt ihr überhaupt mein Problem verstanden, manchmal umschreibe ich das wirklich etwas wirr... :roll: :mrgreen:

DeddyH 27. Okt 2010 08:10

AW: Buttonabhängiges Schließen des Programms
 
Entweder Form1 vorher erzeugen oder die Daten zwischenspeichern (beispielsweise in einer eigenen Klasse oder einem Record) und in Form1 dann wieder auslesen.

Sir Rufo 27. Okt 2010 09:21

AW: Buttonabhängiges Schließen des Programms
 
Das Problem liegt tiefer im Fehlen von Grundlagen.

Ein AccessFehler kommt immer dann, wenn man auf eine Struktur (Klasse) zugreifen möchte, wo es aber keine gültige Instanz gibt.

Delphi-Quellcode:
type
  TFoo = class
    Data : string;
  end;

var
  foo : TFoo;
begin
  foo.Data := 'Hallo'; // <- AccessFehler

  foo := TFoo.Create;
  foo.Data := 'Hallo'; // Alles ok
  foo.Free;

  foo.Data := 'Hallo'; // <- AccessFehler

  foo := TFoo.Create;
  foo.Data := 'Hallo'; // Alles ok

  foo := nil; // <- Upps, ein Speicherleck erzeugt

  foo.Data := 'Hallo'; // <- AccessFehler
end;
Mit einem Beispiel aus dem Leben gegriffen, könnte man es so erklären:
Zitat:

Du planst in deinem Zimmer ein Regal aufzustellen. Das Regal soll rot, 1.5m hoch und 1m breit werden.

Wenn du jetzt in dieses Regal ein Buch stellst, fällt das auf den Boden (ein Absturz), weil du hast das Regal noch nicht gekauft (Instanz)

DeddyH 27. Okt 2010 09:24

AW: Buttonabhängiges Schließen des Programms
 
Wieso, die Ursache hat er doch schon selbst erkannt.
Zitat:

Vom Prinzip kein Problem, aber wenn der Client sich mit dem Server connected hat, wird (im Moment noch) im Verlaufsfenster (des noch nicht erzeugten Form1) einige Informationen angezeigt. Da kommte natürlich eine Fehlermeldung, dass ein AccessFehler aufgetreten ist.

Sir Rufo 27. Okt 2010 09:31

AW: Buttonabhängiges Schließen des Programms
 
Zitat:

Zitat von DeddyH (Beitrag 1058062)
Wieso, die Ursache hat er doch schon selbst erkannt.
Zitat:

Vom Prinzip kein Problem, aber wenn der Client sich mit dem Server connected hat, wird (im Moment noch) im Verlaufsfenster (des noch nicht erzeugten Form1) einige Informationen angezeigt. Da kommte natürlich eine Fehlermeldung, dass ein AccessFehler aufgetreten ist.

Meiner Meinung hat er das Symptom erkannt aber nicht die wirkliche Ursache
Zitat:

Zitat von hans ditter (Beitrag 1057945)
Delphi-Quellcode:
var
  DataModule: Unit3.TDataModule3;
Während der Entwicklungszeit geht das auch alles ohne Fehler. Der Fehler tritt aber auf, wenn
Delphi-Quellcode:
DataModule.ClientSocket.Port:=MY_PORT;
aufgerufen wird.
Dann sagt er, dass eine EAccessViolation aufgetreten ist. Wie hab ich das dann denn zu verstehen?

Auch hier der klassische Fall. Er wollte den Zugriff verkürzen
Zitat:

Zitat von hans ditter (Beitrag 1057762)
Mir ist aber aufgefallen, dass man immer
Code:
Unit3.DataModule3.{...}
schreiben muss, um auf Komponenten zugreifen zu können. Geht das nicht einfacher? Das man irgendwie definieren kann, dass
Delphi-Quellcode:
var Unit3.DataModule3: DataModule;
ist?

und baut sich da was mit
Delphi-Quellcode:
DataModule: Unit3.TDataModule3;
und wundert sich, warum er einen AccessFehler bekommt.
Gelöst hat er das dann so
Zitat:

Zitat von hans ditter (Beitrag 1057959)
Ok, Problem hat sich gerade erledigt. Es reicht wenn ich DataModule3.{...} schreibe. Das reicht mir, ist kurz genug... ;)

Das ist zwar so richtig, aber man kann hier nicht von Erkenntnis sprechen, eher von Zufall

DeddyH 27. Okt 2010 09:44

AW: Buttonabhängiges Schließen des Programms
 
Mir scheint eher, dass er damit Probleme hat, zu wissen, was wann vorhanden ist.

Sir Rufo 27. Okt 2010 09:50

AW: Buttonabhängiges Schließen des Programms
 
Zitat:

Zitat von DeddyH;
Mir scheint eher, dass er damit Probleme hat, zu wissen, was wann vorhanden ist.

und warum es überhaupt vorhanden ist

hans ditter 29. Okt 2010 11:30

AW: Buttonabhängiges Schließen des Programms
 
Naja, habt ihr beiden wohl nicht so unrecht. Ich weiß nicht, wie ihr programmieren gelernt habt und wann, aber ich bring mir das (hauptsächlich) selbst bei, aus Büchern, viel Internet und eben diesem Forum. Die Informatik AG (10. Klasse) konnte ich auch leider nicht komplett machen, da bin ich auch erst später eingestiegen. Und da bei mir keiner ist, der Ahnung davon hat und mir Tipps gibt, womit ich anfangen sollte und wie ich weiter machen sollte, mache ich irgendwie und das was mir gerade in den Sinn kommt... dabei überspring ich dann wohl manches (wichtige)... :roll:

Ich werd mich nochmal ransetzten und über das letzte Problem nachgrübeln... wenn ich mal wieder Zeit hab... :roll: ****** Schule... ;)

Auf jeden Fall vielen Dank für eure Hilfe, ich werd mich in diesem Thread auf jeden Fall nochmal rühren, wenn ich einen Ansatz gefunden hab. Ach ja, und vielen Dank, dass ihr mir klar gemacht habt, wo mein (vielleicht) größtes Problem liegt. Ich werd mal versuchen das aus der Welt zu schaffen!

LG, hans ditter

DeddyH 29. Okt 2010 11:33

AW: Buttonabhängiges Schließen des Programms
 
Gern geschehen :) Das sollte übrigens keine Kritik an Deiner Person sein, nicht dass Du Dich jetzt auf den Schlips getreten fühlst.

hans ditter 29. Okt 2010 17:17

AW: Buttonabhängiges Schließen des Programms
 
Nein, hab ich auch nicht so verstanden!!:!:
Das ist sogar gut, dann kann ich dagegen was unternehmen (hoffe ich zumindest ;)).


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:56 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