![]() |
alternative zu waitforevent
Hey!
Ich bins mal wieder. Hab mal wieder ein Neulingsproblem :). Und zwar hab ich hier ein Programm, dass Userdaten aus einer Textdatei einliest. Diese Textdatei kann immer wieder editiert werden, allerdings existiert sie beim allerersten Programmaufruf natürlich noch nicht. Versuche ich aber dann, sie zu öffnen, krieg ich natürlich einen EFOpenerror. Daher habe ich es zuerst versucht mit try-except und dann on EFOpenerror do abzufangen. Das hat dann sogar irgendwann geklappt, allerdings traten dann irgendwelche total merkwürdigen Probleme auf, naja aber drum gehts jetzt auch gar nicht, sondern es geht um das Folgende: Ich überprüfe jetzt mit if fileexists ob die Datei vorhanden ist. Ist sie das, soll sie ausgelesen werden. Ist sie es aber NICHT, soll createuserprofiles aufgerufen werden. Diese Prozedur tut eigentlich auch nicht mehr, als ein zweites Formular aufzurufen, indem man dann die Userdaten zum ersten Mal einstellen kann. So weit, so gut. Die Einstellungen werden in dem formular dann mit form2.button1click; gespeichert. Nun soll aber die ursprüngliche Prozedur aber so lange warten, bis dieses ereignis ausgelöst wurde, dann noch mal etwa eine sekunde warten, um form2.button1click die Möglichkeit zu geben, alles zu speichern. Nun hab ich mich schon endlos umgesehen wie das wohl geht, und bin da auf waitforevent gestoßen. Dazu hab ich zwar auch dir 3 Parameter gesehen, was die aber bewirken ist mir völlig unklar, außerdem kennt mein delphi die prozedur eh nicht und ich hab nicht rausfinden können, was man unter uses einbinden muss, damit es sie kennt. Deswegen hab ich mir einfach selbst ne ziemlich blöde Schleife gebastelt, die eigentlich nur darauf warten soll, dass dieses durchlaufen (eine booolvariable) auf true gesetzt wird. Sie wird ganz am ende von form2.button1click auf true gesetzt. Aber ich versteh einfach nicht warum das nciht klappt:
Delphi-Quellcode:
Das sollte sie doch eigentlich warten lassen, oder? Naja im Prinzip tut sie das sogar vielleicht, jedenfalls erscheint die Showmesssage die ich darunter eingebaut habe, gar nicht erst. Aber die Prozedur, die nun diese Prozedur aufruft, läuft schon weiter, das erkenn ich immer an der Fehlermeldung, die ich bekomme, weil die userdaten nicht eingelesen wurden.
repeat begin
sleep(100); end until form1.durchlaufen = true; showmessage('Schleife wurde durchlaufen'); Naja meine Frage ist jetzt im Prinzip, wie würdet ihr auf das Ereignis form2.button1click warten? und zwar so, dass KEINE EINZIGE sonstige prozedur weiterläuft bis auf eben form2.button1click? Ich weiß das Problem ist 1. etwas komplexer und 2. blöd formuliert, aber ich hoffe es ist klar geworden, worum es geht. Mfg, Maltimore |
Re: alternative zu waitforevent
Schau dir mal ShowModal an.
|
Re: alternative zu waitforevent
Sleep() wartet aktiv! Und da keine Threads verwendet werden, macht das Programm auch nichts anderes mehr. Die Bedingung wird nie wahr -> Endlosschleife
|
Re: alternative zu waitforevent
@ mkinzler: ähm was du sagst klingt erstmal logisch. es ist aber keine endlossschleife, da sonst ja kaum eine fehlermeldung mit zugriffsverletzung bei adresse soundso kommen könnte. ich habs auch schon mit delay(time: word); auprobiert, klappt aber ebenfalls nicht.
showmodal hab ich noch nie gehört, das seh ich mir jetzt gleich mal an! Danke schonmal für die Hilfe, Maltimore |
Re: alternative zu waitforevent
Zitat:
zudem sollte man bei Boolean-Variablen nie auf False oder True prüfen Z.B. Statt
Delphi-Quellcode:
besser
if form1.durchlaufen = true then ...
Delphi-Quellcode:
if form1.durchlaufen then ...
|
Re: alternative zu waitforevent
hm ok wie gesagt deine antwort klingt sehr logisch.. und ich würde auch niemals was dagegen sagen aber wenn ich es starte kommt nunmal ein error in einer zeile weit darunter.. aber wenn das programm in der endlosschleife gefangen wäre dürfte das doch nicht gehen. oh man das mach mich echt fertig. :wall:
Zu showmodal: Das hab ich mir genau angeguckt, scheint genau das richtige zu sein, allerdings zeigt er mir ne zugriffsverletzung wenn ich versuche, mein form2 mit .showmodal statt mit .show zu öffnen :( mfg, Maltimore |
Re: alternative zu waitforevent
Wo kommt die Zugriffsverletzung und wie lautet die Nachricht?
|
Re: alternative zu waitforevent
Du solltest vielleicht etwas mehr Code zeigen
|
Re: alternative zu waitforevent
Hallo!
Ja klar gerne gebe ich noch mehr Code, das ist hier ja kein Mega-Geheimprojekt! Es ist ein Irc-ähnlicher Chat. Wundert euch bitte nicht über euch komisch vorkommende Zeilen, wenn ich zum beispiel ip und channel erstmal konstant setze usw., das brauch ich jetzt nur zum testen! also erstmal die formcreate, die den ganzen schnodder dan später aufruft:
Delphi-Quellcode:
dann die loadstringfromfile, die ich hier aus dem forum weitestgehend übernommen habe:
procedure TForm1.FormCreate(Sender: TObject);
var information : string; begin durchlaufen := false; standardnick := ''; standardchannel := ''; ip := '85.214.40.83'; channel := 'Willkommen'; dateipfad := 'C:\Programme\ChatclientbyMalteundSoeren'; information := '1337/85.214.40.83/Maltimore/Willkommen'; loadstringfromfile(dateipfad+'\userdaten.txt', information); //hier geht der ärger los!! if durchlaufen then showmessage ('durchlaufen ist true'); sleep(1000); port := Form1.wertzurueck(1, Information); ip := Form1.wertzurueck(2, Information); standardnick :=Form1.wertzurueck(3, Information); channel :=Form1.wertzurueck(4, Information); memo1.Clear; listbox1.items.add('Userlist'); edit1.text := 'Nachricht eingeben'; ClientSocket1.Host:= ip; ClientSocket1.Active:=true; repeat begin Nickname := inputbox('Username', 'Bitte geben sie einen gültigen Usernamen ein', standardnick); if length(nickname) > 20 then showmessage('Es dürfen nicht mehr als 20 Zeichen sein!'); end; until length(nickname) < 21; form1.Caption := 'Angemeldet als: ' + Nickname + ' ||| Channel: Willkommen'; Form1.Anmelden; end;
Delphi-Quellcode:
und noch die createuserprofile:
procedure LoadStringFromFile(Filename: string; var LoadString: string);
var fs: TFileStream; begin // DER FEHLER IST DAS FORM2.show so schnell durchlaufen wird das man keine chance // hat die sachen einzugeben! Programm muss hier warten! if fileexists(loadstring) = true then begin showmessage('fileexists ist true'); fs := TFileStream.Create (Filename, fmOpenRead or fmShareDenyNone); end else begin showmessage('fileexists ist false'); form1.createuserprofile; while form2.modalresult = 0 do application.processmessages; fs := TFileStream.Create (Filename, fmOpenRead or fmShareDenyNone); end; try SetLength (LoadString, fs.Size); if fs.size>0 then fs.Read (LoadString[1], fs.Size); finally fs.Free; end; end;
Delphi-Quellcode:
und wenn hier noch die form2.button1click, bei der dann das modalresult auf mrok gesetzt werden soll:
procedure Tform1.createuserprofile;
begin form2.Showmodal; //hier soll später noch mehr rein, mir ist klar dass es sonst keinen sinn macht, //für form2.showmodal ne eigene prozedur zu bauen end;
Delphi-Quellcode:
So, ich hoffe das war jetzt nicht ZU viel :)
procedure TForm2.Button1Click(Sender: TObject);
var stringi: string; var Text_Datei : TextFile; var pport, pip: bool; begin pport := false; pip := false; stringi := ''; stringi := Edit1.Text + '/' + Edit2.Text + '/' + Edit3.text + '/' + edit4.text + '/'; form1.port := edit1.text; form1.ip := edit2.Text; form1.standardnick := edit3.Text; form1.standardchannel := edit4.Text; AssignFile (Text_Datei,form1.dateipfad+'\userdaten.txt'); Rewrite(Text_Datei); Write(Text_Datei,stringi); CloseFile(Text_Datei); form1.durchlaufen := true; form2.modalresult := mrOK; //das hier ist da wohl das wichtigste für euch if alterport <> form1.port then pport := true; if alteip <> form1.ip then pip := true; form1.werteuebernehmen(pport, pip); form2.Close; end; Wäre euch unendlich dankbar, wenn ihr den Fehler finden würdet. |
Re: alternative zu waitforevent
Was ist die Nachricht der Zugriffsverletzung? Bei modalen Formularen musst du übrigens nicht Close aufrufen.
|
Re: alternative zu waitforevent
oh ja die hatte ich vergessen. Sie sagt mir aber auch gar nichts:
Im Projekt Project1.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei Adresse 0045C6FB' in Modul Project1.exe. Lesen von Adresse 000000000. Prozess wurde angehalten. Mit einzelne Anweisung oder Start fortsetzen. |
Re: alternative zu waitforevent
Weist meistens auf ein nicht instantiiertes objekt hin
|
Re: alternative zu waitforevent
Ähhhm ja. Nicht instanziiertes Objekt. :D Ich bin kompletter Neuling beim Programmieren. Naja nicht soo komplett aber schon ziemlich :)
Hab ich natürlich erstmal gegoogelt: ![]() meinst du, dass ich eine Klasse habe, und einfach ein Objekt benutzt habe, das ich aber gar nicht als Objekt dieser Klasse deklariert habe? Ich bin verwirrt :?: Grüße, Maltimore |
Re: alternative zu waitforevent
Nein. Aber Variablen eines Klassentyps sind Zeiger die anfänglich auf Nil zeigen. Man muss erst ein Instanz erzeugen um mit ihnen arbeiten zu können.
|
Re: alternative zu waitforevent
ok, habe ich glaub ich verstanden. ich hätte dann noch mal ne untertänigste bitte: könnte jemand es hier hinschreiben, oder einen Link posten, um mir die komplette struktur von showmodal und modalresult etc. klarzumachen? ich hab irgendwie das gefühl, dass der fehler da liegt, da ich das einfach mal so ins blaue hinein benutzt habe. Ich bin hier auch schon am googeln aber ne vernünftige erklärung find ich einfach nicht :(
Grüße, Maltimore |
Re: alternative zu waitforevent
ShowModal zeigt ein Formular an und kehrt erst dann zum Aufrufer zurück, wenn im aufgerufen Formular ModalResult gesetzt wurde. Wo kommt überhaupt die AV?
|
Re: alternative zu waitforevent
Schau mal in deiner Delphihilfe unter diesen Begriffen nach ;-)
|
Re: alternative zu waitforevent
@ quendoline: ja das mit der delphi hilfe hätte ich schon längst gemacht, aber die funktioniert unter vista nicht -.-
ähm ja die accessviolation geschieht genau bei form2.showmodal da kommt die sofort. aber bei form2.show nicht. :( oh man.. Liebe Grüße, Maltimore |
Re: alternative zu waitforevent
Zitat:
Zitat:
Nun rufst du im OnCreate-Ereignis der Form1 loadstringfromfile auf, welches in sich wiederum createuserprofile und anschließend dort form2.Showmodal aufruft. Die AV kommt daher, das nun Form2 als Objekt noch nicht existiert, d.h. wird auf einen inkonsistenten Bereich (nil) im Speicher verwießen und das geht natürlich schief. Abhilfe wäre nun, das ganze in das OnShow von Form1 auszulagern anstatt OnCreate, da nun auch Form2.OnCreate durchlaufen wurde, oder du änderst die Erstellungsreihenfolge und lässt Form2 vor Form1 erstellen. |
Re: alternative zu waitforevent
Zitat:
Zitat:
Zitat:
![]() ok, ich merke, ich bin ganz kurz vorm ziel. Nur eine Frage noch: Wie ändere ich denn die Entstehungsreihenfolge der Formulare? O.o ok könnt ich jetzt auch noch googeln, mach ich gleich auch, könnte ja aber trotzdem jemand netterweise hier reinschreiben, eventuell für andere die gleiche Probleme haben :) Also ich will euch hier aber wirklich keine unnötige Last aufbürden, wenn ihr nicht wollt, lasst es :P Vielen, vielen Dank erstmal allen Helfern! Grüße, Maltimore |
Re: alternative zu waitforevent
So. Freunde, wer hätte gedacht, dass das so komplicated wird :)
Schade, dass es dann doch keiner gepostet hat, ich denke mal ihr wisst es, oder? hab gegoogelt und gegoogelt aber es nicht gefunden. letztendlich hab ich eine von-hinten-durch-die-brust-ins-auge methode gewählt:
Delphi-Quellcode:
tja ich würde es gerne anders machen, habs aber wirklich nicht gefunden, wies geht ^^.
procedure form1.formcreate(Sender: TObject);
begin Form2 := TForm2.Create(Application); // sagt nichts :P Maltimore |
Re: alternative zu waitforevent
Reihenfolge kann man in den Projektoptionen einstellen oder manuell im Projekt (dpr)
|
Re: alternative zu waitforevent
Die Lösung ist korrekt. Ich würde -mit Ausnahme des Hauptformulars- keine anderen Formulare automatisch erzeugen.
Wenn Form1 nun mit Form2 interagiert, also Daten usw austauscht, dann sollte Form1 eben im FormCreate die Form2 auch instantiieren ('Create' aufrufen). Natürlich musst Du dann im Form1.FormDestroy die Form2 wieder freigeben (Form2.Free). Alternativ kannst Du die Formulare auch mit Hilfe von
Delphi-Quellcode:
Erzeugen. Dann wird das Formular beim Programmende automatisch freigegeben. Ich halte jedoch nicht viel davon, denn man hat wieder keine Kontrolle in welcher Reihenfolge die Formulare freigegeben werden.
Application.CreateForm(TForm2, Form2);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 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 by Thomas Breitkreuz