Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DFM-Datei automatisch erstellen und zur Laufzeit laden? (https://www.delphipraxis.net/35156-dfm-datei-automatisch-erstellen-und-zur-laufzeit-laden.html)

BerTa 3. Dez 2004 10:36


DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Hallo,

ich lege zur Zeit eine grafische Oberfläche auf eine Cobol-Anwendung mit ca. 2000 Text-Masken. Dazu habe ich einen Generator geschrieben, der mir aus den Masken SQL-Scripts erzeugt, mit denen Labels, Edit-Felder und Buttons mit deren Größe und Position usw. in einer MySql-Datenbank hinterlegt werden. Zur Laufzeit werden dann, je nach Cobol-Programm, die entsprechenden Forms dynamisch erzeugt. Das funktioniert zwar, ist aber je nach Rechner und Netzgeschwindigkeit manchmal ein bischen langsam. Deshalb meine Frage: Kann man zur Design-Zeit eine DFM-Datei automatisch erzeugen, aus der Delphi zur Laufzeit die entsprechende Form darstellt?

Vielen Dank für eine evtl. schnelle Hilfe.

Gruss, Börni

Bernhard Geyer 3. Dez 2004 10:44

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Zitat:

Zitat von BerTa
Hallo,

ich lege zur Zeit eine grafische Oberfläche auf eine Cobol-Anwendung mit ca. 2000 Text-Masken. Dazu habe ich einen Generator geschrieben, der mir aus den Masken SQL-Scripts erzeugt, mit denen Labels, Edit-Felder und Buttons mit deren Größe und Position usw. in einer MySql-Datenbank hinterlegt werden. Zur Laufzeit werden dann, je nach Cobol-Programm, die entsprechenden Forms dynamisch erzeugt. Das funktioniert zwar, ist aber je nach Rechner und Netzgeschwindigkeit manchmal ein bischen langsam. Deshalb meine Frage: Kann man zur Design-Zeit eine DFM-Datei automatisch erzeugen, aus der Delphi zur Laufzeit die entsprechende Form darstellt?

Vielen Dank für eine evtl. schnelle Hilfe.

Gruss, Börni

Du brachst keine DFM-Dateien. Einfach die Controls dynamisch erzeugen.
Das folgende Beispiel erzeugt ein Edit-Feld an der Position 100,100 auf einem Formular:
Delphi-Quellcode:
procedur Button1Click(Sender: TObject);
var
  myEdit: TEdit;
begin
  myEdit := TEdit.Create(self);
  myEdit.Left := 100;
  myEdit.Top := 100;
  myEdit.Parent := self;
//  myEdit.OnChange := MyOnEditChange; <- Events verknüpfen

BerTa 3. Dez 2004 10:49

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Hi Bernhard,

das ist doch genau das was ich mache, ich suche nur nach einer schnelleren Lösung.

Danke

Orbmu2k 3. Dez 2004 10:53

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Erstellst du die Formulare bei Aufruf des jeweiligen oder alle beim Start der Anwendung ?

BerTa 3. Dez 2004 11:00

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Hi,

ich erstelle die Forms, wenn das entsprechende Programm im Menübaum ausgewählt wird.

Bernhard Geyer 3. Dez 2004 11:06

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Zitat:

Zitat von BerTa
das ist doch genau das was ich mache, ich suche nur nach einer schnelleren Lösung.

Ich dachte das macht bisher dein COBOL-Programm.

Zur Geschwindigkeit:
- Wieviel Controls sind auf dem Formular?
- Wann werden die Controls erzeugt (im Konstruktor des Formulars oder im OnShow-Event)?

Eine Verwendung einer DFM-Datei ist prinzipbedingt langsamer als das direkte anlegen der Controls im Code, da hier noch Rechenzeit für das Parsern der DFM-Datei benötigt wird.

Orbmu2k 3. Dez 2004 11:12

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
ist die Datenbank im Lokalen Netz angebunden oder Internet ?

Ich meine das Proggi muss ja auch erstmal an die Daten ran kommen ....

Dann kann man seine SQL abfragen auch noch optimieren (grade bei mysql)


MySQL
SQL-Code:
// MySQL Langsam -> DB2 Genauso schnell wie siehe unten

select a.Feld

from GrosseTabelle a

left join KleineTabelle b

where b.Feld in (1,2,3)

// MySQL und DB2 gleichschnell

select a.Feld

from Kleine Tabelle b

left join GrosseTabelle a

where b.Feld in (1,2,3)

OLLI_T 3. Dez 2004 11:13

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Hallo Börni!

Der Flaschenhals bei der Geschichte ist sicherlich das Netzwerk und das Auslesen der Control-Properties aus der DB. Vielleicht bringt ein Index in der DB etwas Speed?

Schliesse mich der Frage von Bernhard an: Wieviele Controls sind es denn pro Formular?

Gruss

Der OLLI

BerTa 3. Dez 2004 11:33

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Hallo Bernhard,

ich hatte mich nicht ganz klar ausgedrückt, gerade für die Oberfläche brauche ich Delphi, weil mir das in COBOL (reine API-Programmierung) zu stressig ist.

Hier meine Programm-Struktur:

Das Grundprogramm mit Menübaum usw. ist eine Delphi-exe. Beim Auswählen eines Programms wird eine Delphi-Dll XY als MDI-Child aufgerufen, welche den Hintergund mit einem PageControl erzeugt. Danach wird die entsprechende COBOL-Dll aufgerufen. Dessen Anzeigeprogramm (für die alten textbasierten Masken-Dialoge) habe ich so umgebaut, dass eine exportierte Funktion in der selben Delphi-dll XY aufgerufen wird, die mir je nach Programm mehrere TabSheets in dem besagten PageControl erzeugt. Die Komponenten sind halt in MySql-Tabellen hinterlegt, die ich mit der Hilfe von Zeos-Komponenten lese. Bei einer Maske habe ich noch kein Problem, aber wenn ich 4-5 TabSheets mit jeweils ca. 50 Komponenten erzeuge, dann kann's schon etwas dauern...

Gruss Börni

BerTa 3. Dez 2004 11:40

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Ich denke nicht dass es unbedingt die Datenbank ist, sicher kann man das noch optimieren. Bei einer lokalen Datenbank habe ich das gleiche Problem. Ich könnte die Beschreibung der Forms auch in einer Textdatei hinterlegen, bloss dann müsste ich diese auf jedem Platz mitinstallieren, damit das Netz nicht so belastet wird. Deshalb war mein Gedanke, eine Maske aus meinen Daten schon vorgenerieren und in der COBOL-DLL mit unterbringen.

Gruss, Börni

Bernhard Geyer 3. Dez 2004 11:44

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Baust Du dann auch in der DLL eine eigene Verbindung mit der Datenbank auf?
Wieso denn alles in eigene DLL's auslagern. Es ist doch viel einfacher (und auch von der gesamten größer (Exe+DLL's) sparsammer alles in eine Anwendung zu halten. Damit kommst Du auch nur mit einer einzigen DB-Verbindung aus.

Es könnten verschiedene Ursachen haben:
- In jeder DLL wird eine DB-Verbingung aufgebaut (dauert auch ein paar ms)
- Die Abfragen sind supoptimal (zu große Ergebnismenge)
- ...

Falls Du ein paar € ausgeben kannst, würde ich AQTime empfehlen. Hab damit schon teilweise die Performance auf das 10-100fache erhöht, da damit sehr einfach die Performancekritischen Stellen bis auf Codezeilen gefunden werden kann.

maximov 3. Dez 2004 12:13

Re: DFM-Datei automatisch erstellen und zur Laufzeit laden?
 
Ja, AQTime is echt ganz toll. Aber um auf deine ursprüngliche frage zurück zu kommen:

Zitat:

Kann man zur Design-Zeit eine DFM-Datei automatisch erzeugen, aus der Delphi zur Laufzeit die entsprechende Form darstellt?
Du kannst in delphi jede beliebige komponente, mit unterkomponenten, streamen lassen. Das muss nicht unbedingt ein form sein. Dh. du könntest auch sagen, dass du nur den inhalt einer Tabs streamst, und in deiner DB speichert.

Das ganz geht, wie der ausdruck 'streamen' schon sagt mit einem stream. Und zwar mit jedem stream in delphi:

Delphi-Quellcode:
Stream.WriteComponent(aCompo);
...
Stream.ReadComponent(aCompo);
Ich hab das früher mal für filestreams gemacht. Da is auch noch die umwandlung in Text-DFMs mit drinne, die du evtl. weglassen könntest, oder nur zur kontrolle aktivieren. Und evtl redundante streams optimieren:

Delphi-Quellcode:
function SaveCompoToFile(aCompo : TComponent; FileName: string; asBinary: Boolean = false): boolean;
var Stream1:TMemoryStream;
    Stream2:TMemoryStream;
      format : TStreamOriginalFormat;
begin
  result := false;
   format := sofText;
   Stream1 := TMemoryStream.Create;
  Stream2 := TMemoryStream.Create;
   try
      Stream1.WriteComponent(aCompo);
    Stream1.Position := 0;
    if not asBinary then
    begin
      format := sofText;
      ObjectBinaryToText(Stream1,Stream2,format);
    end else Stream1.SaveToStream(Stream2);
    Stream2.SaveToFile(FileName);
    result := true;
   finally
      Stream1.Free;
      Stream2.Free;
   end;
end;


function LoadCompoFromFile(aCompo : TComponent; FileName: string; asBinary: Boolean = false): boolean;
var FileStream:TFileStream;
    MemoryStream:TMemoryStream;
    format:TStreamOriginalFormat;
begin
  result := false;
  if not FileExists(fileName) then exit;
  MemoryStream := TMemoryStream.Create;
  FileStream := TFileStream.Create(FileName,fmOpenRead);
  try
    if not asBinary then
    begin
      format := sofBinary;
      ObjectTextToBinary(FileStream,MemoryStream,format);
    end else MemoryStream.LoadFromStream(FileStream);
    MemoryStream.Position := 0;    
    MemoryStream.ReadComponent(aCompo);
    result := true;
  finally
    FileStream.Free;
    MemoryStream.Free;
  end;
end;
Viel spass :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:35 Uhr.

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