Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Kann man ein 2. Fenster im FormCreate von form1 aufrufen?
zero-2-one - So 01.04.07 18:11
Titel: Kann man ein 2. Fenster im FormCreate von form1 aufrufen?
Hallo,
mein Problem ist, dass ich zu begin meines Programstartes überprüfen will, ob eine ini-datei vorhanden ist. Falls ja ist alles super und das programm kann ablaufen - falls nicht, dann will ich direkt ein 2. Fenster öffnen in dem einige wichtige Angaben (Pfade, Einstellungen, etc.) abgefragt werden.
Bisher sieht das mal vereinfacht so aus:
Hier Unit1:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Label1: TLabel; Button1: TButton; procedure FormCreate(Sender: TObject); private public end;
var Form1: TForm1;
implementation
uses unit2;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); var s: string; begin GetDir(0,s); if not FileExists(s+'settings.ini') then begin label1.Caption := 'Settings.ini in Verzeichniss ' + s + ' nicht vorhanden'; form2.show(); end else begin label1.Caption := 'Settings.ini in Verzeichniss ' + s + ' bereits vorhanden'; end; end;
end. |
und hier Unit2:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| unit Unit2;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm2 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); private public end;
var Form2: TForm2;
implementation
uses Unit1, iniFiles;
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject); var s: string; ini: tIniFile; begin GetDir(0,s); ini:=TIniFile.create(s+'\settings.ini'); ini.WriteString('Allgemein','user','Testbenutzer'); ini.WriteInteger('Allgemein','Anker',0); ini.WriteInteger('Allgemein','Vordergrund',1); ini.WriteInteger('Allgemein','orientieren',1); form1.label1.caption := 'Settings.ini wurde neu erstellt'; end;
end. |
Beim kompilieren kommt dann ne Exception der Klasse EAccessViolation und nach bestätigen auf OK springt er in das Fenster Project1 und beschwert sich über die makierte Zeile:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| program Project1;
uses Forms, Unit1 in 'Unit1.pas' , Unit2 in 'Unit2.pas' ;
{$R *.res}
begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.CreateForm(TForm2, Form2); <----- diese Zeile wird angemekert. Application.Run; end. |
ich bin mir jetzt nicht sicher ob ich was falsch mache oder das einfach nicht geht. Wenn ich den Befehl Form2.show() mit TForm1.Button1Click aufrufe, dann geht übrigens alles problemlos aber das hilft mir leider bei meinem Problem nicht weiter.
Danke schonmal für eure Hilfe.
Alex
JayEff - So 01.04.07 18:19
Pass auf:
Der PC Arbeitet deine Projektdatei Zeile für Zeile ab. Er stößt auf CreateForm(TForm1, Form1);
Nun springt der ins onCreate dieser Form und findet Form2.Show; Oha! denkt er sich; Es gibt keine Form2! (Da CreateForm(TForm2...) noch nicht aufgerufen wurde) und bricht die Prozedur ab. Am Ende der Prozedur, also praktisch nach der Zeile CreateForm(Form1..); wirft er also den Fehler auf und deutet auf das CreateForm(Form2..); obwohl der Fehler in CreateForm(Form1...) aufgetreten ist ;)
Lösung sollte sein, den Code aus dem Form1Create ins Form1Show auszulagern, da das Show nach dem Create der anderen Forms ausgeführt wird. Sollte das immernoch nicht klappen, kannst du es ins onPaint auslagern. Schreib dir dazu dann aber eine Booleanvariable, über die du steuerst, dass der Code nur einmal ausgeführt werden kann, da sonst bei jedem Neuzeichnen der Form1 die Form2 angezeigt werden könnte ;)
Edit: Im onShow gehts nicht? Aus welchem Grund denn? Ich meine, warum muss es denn im onCreate sein? Du kannst zwar das Create von Form2 nach oben schieben, aber ich bin mir nicht sicher, ob es dann nicht einen Fehler gibt ... :/
MrSaint - So 01.04.07 18:31
Sauberer wäre es wohl den Code für die Abfrage direkt in die Projektdatei zu packen und nicht in ein Ereignis einer Form. Also etwa so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| program Project1;
uses Forms, Unit1 in 'Unit1.pas' , Unit2 in 'Unit2.pas' ;
{$R *.res}
var s: string;
begin Application.Initialize; GetDir(0,s); if not FileExists(s+'settings.ini') then begin form2 := TForm2.Create(nil); try form2.showModal; finally FreeAndNil(form2); end; end; Application.CreateForm(TForm1, Form1); Application.Run; end. |
- ungetestet -
MrSaint
zero-2-one - So 01.04.07 18:43
Ok, hab verstanden warum es nicht funktioniert und auch die Idee hinter beiden Lösungen aber...
@ JayEff:
wie muss das den aussehen mit dieser onShow procedure?
procedure TForm1.Form1onShow();
begin
und hier dann einfach meinen Quelltext aus der Formcreate rein
end;
oder wie komm ich an diese Eigenschaft von Form1 ran? Deinen Edit hab ich übrigens nicht verstanden :(
@ MrSaint:
Habs zwar nochnicht ausprobiert - sieht aber verständlich aus (werds mal testen).
Edit: Fehlen mir in der Project1 dann nicht irgendwelche uses? der Kompiler kennt dann nämlich nicht die Befehle FileExists usw.
Übrigens danke für eure schnellen Antworten - echt der Hammer hier :)
MrSaint - So 01.04.07 18:57
zero-2-one hat folgendes geschrieben: |
@ MrSaint:
Habs zwar nochnicht ausprobiert - sieht aber verständlich aus (werds mal testen).
Edit: Fehlen mir in der Project1 dann nicht irgendwelche uses? der Kompiler kennt dann nämlich nicht die Befehle FileExists usw.
|
Deswegen steht
drunter ;) Mit einmal F1 bekommt man das raus: Es fehlt die
SysUtils, dann sollte es gehen...
MrSaint
zero-2-one - So 01.04.07 19:19
Gut gut, hat geklappt. Aber nur, weil ich den Bezug von form2 zu form1.label1 rausgenommen hab (der war ja eigentlich eh nur zum Testen da) - ansonsten hätte ich ja nochimmer das von JayEff beschriebene Problem gehabt. Deswegen ma danke an euch beide...
@ JayEff: Wenn du nochmal kurz Zeit hast, dann könntest du mir trotzdem noch kurz erklären, wie das mit dem "OnShow" bei Form1 im Quelltext aussehn müsste - würde das auch gerne mal ausprobieren
thx Alex
JayEff - So 01.04.07 23:54
zero-2-one hat folgendes geschrieben: |
@ JayEff: Wenn du nochmal kurz Zeit hast, dann könntest du mir trotzdem noch kurz erklären, wie das mit dem "OnShow" bei Form1 im Quelltext aussehn müsste - würde das auch gerne mal ausprobieren
|
Im Anhang hab ich ein Bild. Dort, wo der Cursor blinkt, musst du nur doppelklicken, schon bekommst du den genauen Prozedurenkopf vom onShow-Ereignis der Form, der auch gleich dem Handler zugewiesen ist.
Das onShow-Ereignis wird ausgelöst, wenn die Form angezeigt wird - IIRC werden erst alle Formen erzeugt, bevor die Hauptform angezeigt wird. (Das Ereignis wird (IIRC) auch bei Form1.Show; ausgelöst, darum evtl. per boolean-Variable dafür sorgen, dass der Code nur einmal ausgeführt wird:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var shown: Boolean;
Procedure TForm1.FormShow(Sender: TObject); Begin If Not shown Then Begin deinCode; shown := true; End; End; |
zero-2-one - Mo 02.04.07 00:03
super danke :)
man merkt, dass es wirklich schonwieder en paar jährchen her ist, als ich noch mit delphi gearbeitet hab...
Die grundlegenden sachen mit ereignissen hab tatsächlich wieder vergessen - aber klasse das man hier so nett geholfen bekommt. Die Boolean variable kann ich mir ja aber eigentlich sparen, da ja immer geprüft wird, ob die settings.ini schon exisitiert und wenn nicht, dann wird Sie für das nächste mal erstellt.
Na denn bis die Tage zu meiner nächsten Frage - zumindest rechne ich stark mit weiteren Fragen meiner Seits
Alex
JayEff - Mo 02.04.07 00:14
zero-2-one hat folgendes geschrieben: |
Na denn bis die Tage zu meiner nächsten Frage - zumindest rechne ich stark mit weiteren Fragen meiner Seits |
Ich werde da sein ... Ich werde warten ... Meine Zeit wird kommen ... Muahahahaaa! :twisted:
..edit: Vielleicht kannst du grad noch das Thema als erledigt markieren? Unter dem letzen Beitrag dürfte ein Link "HIER" stehen ... :)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!