Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   alternative zu waitforevent (https://www.delphipraxis.net/135195-alternative-zu-waitforevent.html)

Maltimore 6. Jun 2009 11:27


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:
repeat begin
  sleep(100);
end until form1.durchlaufen = true;
showmessage('Schleife wurde durchlaufen');
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.
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

Apollonius 6. Jun 2009 11:34

Re: alternative zu waitforevent
 
Schau dir mal ShowModal an.

mkinzler 6. Jun 2009 11:35

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

Maltimore 6. Jun 2009 12:35

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

mkinzler 6. Jun 2009 12:40

Re: alternative zu waitforevent
 
Zitat:

es ist aber keine endlossschleife,
Doch, weil sich an dem Wert von form1.durchlaufen nichts ändert.
zudem sollte man bei Boolean-Variablen nie auf False oder True prüfen

Z.B. Statt
Delphi-Quellcode:
if form1.durchlaufen = true then ...
besser
Delphi-Quellcode:
if form1.durchlaufen then ...

Maltimore 6. Jun 2009 13:02

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

Apollonius 6. Jun 2009 13:04

Re: alternative zu waitforevent
 
Wo kommt die Zugriffsverletzung und wie lautet die Nachricht?

mkinzler 6. Jun 2009 13:05

Re: alternative zu waitforevent
 
Du solltest vielleicht etwas mehr Code zeigen

Maltimore 6. Jun 2009 16:50

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:
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;
dann die loadstringfromfile, die ich hier aus dem forum weitestgehend übernommen habe:

Delphi-Quellcode:
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;
und noch die createuserprofile:
Delphi-Quellcode:
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;
und wenn hier noch die form2.button1click, bei der dann das modalresult auf mrok gesetzt werden soll:
Delphi-Quellcode:
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;
So, ich hoffe das war jetzt nicht ZU viel :)
Wäre euch unendlich dankbar, wenn ihr den Fehler finden würdet.

Apollonius 6. Jun 2009 16:57

Re: alternative zu waitforevent
 
Was ist die Nachricht der Zugriffsverletzung? Bei modalen Formularen musst du übrigens nicht Close aufrufen.

Maltimore 6. Jun 2009 17:05

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.

mkinzler 6. Jun 2009 17:06

Re: alternative zu waitforevent
 
Weist meistens auf ein nicht instantiiertes objekt hin

Maltimore 6. Jun 2009 17:20

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: http://www.delphi-treff.de/sprachen/...torientierung/

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

mkinzler 6. Jun 2009 17:24

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.

Maltimore 6. Jun 2009 17:34

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

Apollonius 6. Jun 2009 17:36

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?

quendolineDD 6. Jun 2009 18:49

Re: alternative zu waitforevent
 
Schau mal in deiner Delphihilfe unter diesen Begriffen nach ;-)

Maltimore 6. Jun 2009 19:01

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

quendolineDD 6. Jun 2009 19:07

Re: alternative zu waitforevent
 
Zitat:

@ quendoline: ja das mit der delphi hilfe hätte ich schon längst gemacht, aber die funktioniert unter vista nicht -.-
Ich nutze selber Vista und bei mir geht die Hilfe in TDE, Delphi 2007 und Delphi 2009.

Zitat:

ähm ja die accessviolation geschieht genau bei form2.showmodal da kommt die sofort. aber bei form2.show nicht. Sad oh man..
Und zwar wird bei dir die Erstellungsreihenfolge wie folgt sein: 1. Form 1; 2. Form2

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.

Maltimore 6. Jun 2009 19:15

Re: alternative zu waitforevent
 
Zitat:

Zitat von quendolineDD
Zitat:

@ quendoline: ja das mit der delphi hilfe hätte ich schon längst gemacht, aber die funktioniert unter vista nicht -.-
Ich nutze selber Vista und bei mir geht die Hilfe in TDE, Delphi 2007 und Delphi 2009.

also hier geht es wirklcih nicht, ich kann auch gerne n screenshot schicken, hier erstmal der text, der kommt wenn ich die hilfe zu starten versuche:
Zitat:

Warum kann ich keine Hilfe von diesem Programm erhalten?

Die Hilfe für dieses Programm wurde in einem Windows-Hilfeformat erstellt, das in früheren Versionen von Windows verwendet wurde. Es wird in Windows Vista nicht unterstützt.

Weitere Informationen erhalten Sie unter Die Windows-Hilfeanwendung (WinHelp32.exe) wird in Windows nicht mehr unterstützt. (möglicherweise in englischer Sprache) auf der Microsoft-Supportwebsite.
so, nun zu deinem sehr guten ratschlag:
Zitat:


Zitat:

ähm ja die accessviolation geschieht genau bei form2.showmodal da kommt die sofort. aber bei form2.show nicht. Sad oh man..
Und zwar wird bei dir die Erstellungsreihenfolge wie folgt sein: 1. Form 1; 2. Form2

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.
oh, das ist ein genialer zufall: ich war auch grad wie wild am googlen was es sein könnte, und was finde ich fast zeitgleich mit deinem schreiben:
http://www.wer-weiss-was.de/theme159/article496618.html daraus geht das auch hervor und ich wollte euch grade fragen, ob das bei mir auch der fall sein könnte :)

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

Maltimore 6. Jun 2009 20:57

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:
procedure form1.formcreate(Sender: TObject);
begin
Form2 := TForm2.Create(Application); // sagt nichts :P
tja ich würde es gerne anders machen, habs aber wirklich nicht gefunden, wies geht ^^.

Maltimore

mkinzler 6. Jun 2009 21:04

Re: alternative zu waitforevent
 
Reihenfolge kann man in den Projektoptionen einstellen oder manuell im Projekt (dpr)

alzaimar 7. Jun 2009 18:13

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:
Application.CreateForm(TForm2, Form2);
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.


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