Showmodal

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
HaseCaesar
Beiträge: 27
Registriert: Mi 2. Apr 2014, 09:47

Showmodal

Beitrag von HaseCaesar »

Habe mich heute erst registriert und bitte um Nachsicht, wenn ich das hier nicht alles auf Anhieb raffe! Danke!

Programmiere seit fast 30 Jahren mit Delphi und bin vor einiger Zeit umgestiegen auf Lazarus. Habe eine Delphi-App (Filmverwaltung) nach Lazarus portiert (manuell!).

Folgendes Problem stellt sich heute:

Ein Grid zeigt mir meine Filme zeilenweise an. Habe eine Korrekturfunktion eingebaut. Diese öffnet ein Formular mit Feldern, in die ich die aktuellen Daten übertrage.
Danach rufe ich das Form mit

FKorrigieren.Showmodal

auf. Funktioniert auch (kann, während das Korrekturform sichtbar ist, nicht in das Hauptform klicken) - wie ich das von Delphi her kenne.

ABER: Wenn ich das Korrekturform schließe, läuft der Programmcode nicht ab der nächsten Zeile nach FKorrigieren.Showmodal weiter (habe dort einen Breakpoint gesetzt).

Schließe ich allerdings das Hauptformular (Programm beenden), dann steht der Ausführungspunkt auf meinem Breakpoint (was ich natürlich nicht möchte, denn ab dort sollen ja die Veränderungen, die ich im FKorrigieren-Form gemacht habe, gespeichert werden). Ist das ein Lazarus-Bug oder ein normales Verhalten von Lazarus? Falls normal - wie bekomme ich das dann in den Griff?

Hat jemand eine Idee, warum sich Lazurus SO verhält? Von Delphi kenne ich das nicht.

Vielen Dank im voraus für eure Hilfe.

Hier ein Code-Ausschnitt zum besseren Verständnis:

Code: Alles auswählen

 
procedure TFHaupt.buKorrigierenClick(Sender: TObject);
 
var
     abgebrochen : boolean;
     korrektur_id : integer;
     s : string;
 
begin
     application.CreateForm (TFKorrigieren, FKorrigieren);
 
     FKorrigieren.Caption := 'Film-Info für ' + qu.FieldByName('titel').asstring + ' (Esc zum Schließen)';
     FKorrigieren.teHDName.text := qu.fieldbyname ('hdname').asstring;
     FKorrigieren.tedatum.text := qu.fieldbyname ('datum').asstring;
     FKorrigieren.tejahr.text := qu.fieldbyname ('jahr').asstring;
     FKorrigieren.liformat.itemindex := FKorrigieren.liformat.Items.IndexOf (qu.FieldByName('format').asstring);
     FKorrigieren.tetitel.text := qu.fieldbyname ('titel').asstring;
     FKorrigieren.tebemerkung.text := qu.fieldbyname ('bemerkung').asstring;
     FKorrigieren.tegenre.text := qu.fieldbyname ('genre').asstring;
     FKorrigieren.meinfo.text := qu.FieldByName('info').asstring;
 
     FKorrigieren.showmodal;                       //BIS HIERHER ALLES OK - Form wird modal angezeigt[/color]
 
     abgebrochen := FKorrigieren.modalresult = mrcancel;       //HIER HABE ICH BREAKPOINT GESETZT - allerdings komme ich erst hierher, wenn das Hauptform geschlossen wird!
     if   abgebrochen then
     begin
          FKorrigieren.free;
          exit;
     end;
 
     // Daten wurden bereits auf Gültigkeit im FKorrigieren geprüft - alles ok
     // Datensatz updaten
     with FKorrigieren do
     begin
          s := 'UPDATE `titel`, `datum`, `format`, `jahr`, `genre`, `bemerkung`, `info`, `hdname`,  ' +
               'VALUES (' +
          #39 + tetitel.text + #39 +   ...  ... ...           USW USW
Zuletzt geändert von Lori am So 6. Apr 2014, 15:13, insgesamt 1-mal geändert.
Grund: Highlighter

baumina
Beiträge: 152
Registriert: Mo 3. Feb 2014, 14:07
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Showmodal

Beitrag von baumina »

Also ich bin in der Delphi-Programmierung und habe mit Lazarus noch nichts gemacht, aber eine Zeile macht mich stutzig, die müsste auch in Delphi anders lauten:

Code: Alles auswählen

application.CreateForm (TFKorrigieren, FKorrigieren);
 
sollte so lauten:

Code: Alles auswählen

FKorrigieren := TFKorrigieren.Create(self);
 
Desweiteren liefert ein ShowModal bereits das ModalResult:

Code: Alles auswählen

MyRes := FKorrigieren.ShowModal;
If MyRes = mrCancel ...
.

wp_xyz
Beiträge: 5139
Registriert: Fr 8. Apr 2011, 09:01

Re: Showmodal

Beitrag von wp_xyz »

Warum fragst du nicht das Funktionsergebnis von ShowModal ab?
Ich würde es so machen, dieses Schema funktioniert in allen meinen Delphi und Lazarus Programmen:

Code: Alles auswählen

 
FKorrigieren := TFKorrigieren.Create(nil);
try
  FKorrigieren.Caption := 'Film-Info für ' + qu.FieldByName('titel').asstring + ' (Esc zum Schließen)';
  FKorrigieren.teHDName.text := qu.fieldbyname ('hdname').asstring;
  FKorrigieren.tedatum.text := qu.fieldbyname ('datum').asstring;
  FKorrigieren.tejahr.text := qu.fieldbyname ('jahr').asstring;
  FKorrigieren.liformat.itemindex := FKorrigieren.liformat.Items.IndexOf (qu.FieldByName('format').asstring);
  FKorrigieren.tetitel.text := qu.fieldbyname ('titel').asstring;
  FKorrigieren.tebemerkung.text := qu.fieldbyname ('bemerkung').asstring;
  FKorrigieren.tegenre.text := qu.fieldbyname ('genre').asstring;
  FKorrigieren.meinfo.text := qu.FieldByName('info').asstring;  
 
  if FKorrigieren.showmodal = mrOK then begin
    s := 'UPDATE `titel`, `datum`, `format`, `jahr`, `genre`, `bemerkung`, `info`, `hdname`, ' +
      'VALUES (' +
      #39 + tetitel.text + #39 + ... ... ... USW USW
    // etc. - Änderungen speichern
  end;
finally
  FKorrigieren.Free;
end;
 

HaseCaesar
Beiträge: 27
Registriert: Mi 2. Apr 2014, 09:47

Re: Showmodal

Beitrag von HaseCaesar »

wp_xyz hat geschrieben:Warum fragst du nicht das Funktionsergebnis von ShowModal ab?
Ich würde es so machen, dieses Schema funktioniert in allen meinen Delphi und Lazarus Programmen:

Code: Alles auswählen

 
FKorrigieren := TFKorrigieren.Create(nil);
try
  FKorrigieren.Caption := 'Film-Info für ' + qu.FieldByName('titel').asstring + ' (Esc zum Schließen)';
  FKorrigieren.teHDName.text := qu.fieldbyname ('hdname').asstring;
  FKorrigieren.tedatum.text := qu.fieldbyname ('datum').asstring;
  FKorrigieren.tejahr.text := qu.fieldbyname ('jahr').asstring;
  FKorrigieren.liformat.itemindex := FKorrigieren.liformat.Items.IndexOf (qu.FieldByName('format').asstring);
  FKorrigieren.tetitel.text := qu.fieldbyname ('titel').asstring;
  FKorrigieren.tebemerkung.text := qu.fieldbyname ('bemerkung').asstring;
  FKorrigieren.tegenre.text := qu.fieldbyname ('genre').asstring;
  FKorrigieren.meinfo.text := qu.FieldByName('info').asstring;  
 
  if FKorrigieren.showmodal = mrOK then begin
    s := 'UPDATE `titel`, `datum`, `format`, `jahr`, `genre`, `bemerkung`, `info`, `hdname`, ' +
      'VALUES (' +
      #39 + tetitel.text + #39 + ... ... ... USW USW
    // etc. - Änderungen speichern
  end;
finally
  FKorrigieren.Free;
end;
 


Jetzt wird es richtig lustig. Habe es, wie oben, geändert. Und das Ergebnis? Dasselbe. Nach

if FKorrigieren.showmodal = mrOK then begin ...
wird der Code nicht weiter ausgeführt (obwohl mrOK zutrifft) - und es geschieht dasselbe, daß dort weiter abgearbeitet wird, wenn ich das Hauptform (Programm) schließe. Arbeite mit Lazarus 1.2.0 vom 01.03.14, FPC-Version 2.6.2, SVN-Revision 44306, x86-64-linux gtk 2

Warum verhält sich mein proggi derart?

baumina
Beiträge: 152
Registriert: Mo 3. Feb 2014, 14:07
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Showmodal

Beitrag von baumina »

Ich tippe darauf, dass das Formular FKorrigieren nicht wirklich geschlossen wird, evtl durch OnFormCloseQuery verhindert. Da musst mal dort nachschauen.
.

HaseCaesar
Beiträge: 27
Registriert: Mi 2. Apr 2014, 09:47

Re: Showmodal

Beitrag von HaseCaesar »

baumina hat geschrieben:Ich tippe darauf, dass das Formular FKorrigieren nicht wirklich geschlossen wird, evtl durch OnFormCloseQuery verhindert. Da musst mal dort nachschauen.
kann nicht sein. onclosequery ist nicht gesetzt.

Eb
Lazarusforum e. V.
Beiträge: 240
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Re: Showmodal

Beitrag von Eb »

Ich hatte auch mal ein seltsames Verhalten von showmodal.
Das modale Fenster wurde offensichtlich nicht richtig geschlossen. Trat allerdings nur auf, wenn das modale Fenster mehrfach hintereinander aufgerufen wurden, unter Ubuntu 12.04 und nicht unter Windows.

da wurde ich geholfen:
http://www.lazarusforum.de/viewtopic.ph ... 081#p67081

HaseCaesar
Beiträge: 27
Registriert: Mi 2. Apr 2014, 09:47

Re: Showmodal

Beitrag von HaseCaesar »

Eb hat geschrieben:Ich hatte auch mal ein seltsames Verhalten von showmodal.
Das modale Fenster wurde offensichtlich nicht richtig geschlossen. Trat allerdings nur auf, wenn das modale Fenster mehrfach hintereinander aufgerufen wurden, unter Ubuntu 12.04 und nicht unter Windows.

da wurde ich geholfen:
http://www.lazarusforum.de/viewtopic.ph ... 081#p67081
danke für deine antwort und den link. habe alles gelesen. allerdings wird dort ja ein "etwas anderes" problem geschildert.

mein problem ist ja, daß nach dem schließen des formular im hauptformular NICHT an der nächsten zeile das proggi weiter ausgeführt wird (nach dem showmodal), sondern daß dorthin gesprungen wird, wenn das HAUPTform geschlossen wird.

solch ein verhalten kann ich gar nicht nachvollziehen und hatte es unter delphi in all den jahren nicht. bin mir ziemlich ratlos.

arbeite übrigen - wie der problemkollege aus deinem link - mit gdk.

wp_xyz
Beiträge: 5139
Registriert: Fr 8. Apr 2011, 09:01

Re: Showmodal

Beitrag von wp_xyz »

Ich entnehme dem 1. Posting, dass du Projekte von Delphi zu Lazarus konvertiert. Auch dieses? Vielleicht ist bei der Konvertierung etwas schief gelaufen?

Versuch mal das beigefügte Minimal-Projekt. Bei mir hält der Debugger in der Zeile hinter dem ShowModal einwandfrei an.
Dateianhänge
ShowModal_Issue.zip
(2.7 KiB) 125-mal heruntergeladen

HaseCaesar
Beiträge: 27
Registriert: Mi 2. Apr 2014, 09:47

Re: Showmodal

Beitrag von HaseCaesar »

:wink:
wp_xyz hat geschrieben:Ich entnehme dem 1. Posting, dass du Projekte von Delphi zu Lazarus konvertiert. Auch dieses? Vielleicht ist bei der Konvertierung etwas schief gelaufen?

Versuch mal das beigefügte Minimal-Projekt. Bei mir hält der Debugger in der Zeile hinter dem ShowModal einwandfrei an.
danke für deinen tip und den anhang. werde ich ausprobieren.

du hast recht: ist ein ursprüngliches delphi-proggi. aber ich habe es nicht autom. konvertieren lassen, sondern habe alles "zu fuß" gemacht.
außerdem hatte ich vorher eine eigene sortierroutine geschrieben und alle daten in einer datei vom typ file of TRec gespeichert.
inzwischen arbeite ich mit einer sql-datenbank. habe alles entsprechend umgebaut.

dabei ist noch ein weiteres "problem" aufgetaucht, was ich aber in einem gesonderten thread posten werde. für mich hat momentan oberste priorität,
daß ich das mit dem showmodal in den griff bekomme.

melde mich, was bei mir herausgekommen ist bezüglich deine zip-files.

vielen dank erstmal.

HC

HaseCaesar
Beiträge: 27
Registriert: Mi 2. Apr 2014, 09:47

Re: Showmodal

Beitrag von HaseCaesar »

HaseCaesar hat geschrieben::wink:
wp_xyz hat geschrieben:Ich entnehme dem 1. Posting, dass du Projekte von Delphi zu Lazarus konvertiert. Auch dieses? Vielleicht ist bei der Konvertierung etwas schief gelaufen?

Versuch mal das beigefügte Minimal-Projekt. Bei mir hält der Debugger in der Zeile hinter dem ShowModal einwandfrei an.
danke für deinen tip und den anhang. werde ich ausprobieren.

du hast recht: ist ein ursprüngliches delphi-proggi. aber ich habe es nicht autom. konvertieren lassen, sondern habe alles "zu fuß" gemacht.
außerdem hatte ich vorher eine eigene sortierroutine geschrieben und alle daten in einer datei vom typ file of TRec gespeichert.
inzwischen arbeite ich mit einer sql-datenbank. habe alles entsprechend umgebaut.

dabei ist noch ein weiteres "problem" aufgetaucht, was ich aber in einem gesonderten thread posten werde. für mich hat momentan oberste priorität,
daß ich das mit dem showmodal in den griff bekomme.

melde mich, was bei mir herausgekommen ist bezüglich deine zip-files.

vielen dank erstmal.

HC
Also das ist ja jetzt der Hammer. Dein Proggi funzt einwandfrei. Allerdings erzeugst du das Formular mit (nil) - ich mit (self).
Habe das jetzt bei mir auch mal auf (nil) gesetzt. Keine Änderung. Irgendwas muß bei mir anderes bei den Formularen sein.
Ich suche mal weiter.

Noch einen Tipp für Euch:

Das Korrigieren-Form hat folgende Routinen:

Code: Alles auswählen

buOKClick (wo Gültigkeitsprüfungen stattfinden)
FormClose
buOKClick:
 
     // Eingaben auf Gültigkeit prüfen
     modalresult := mrnone;
 
     if   trim (tetitel.text) = '' then
     begin
          beep;
          showmessage ('Es wurde kein Titel eingegeben!');
          tetitel.setfocus;
          exit;
     end;
 
     try
          // Datum korrekt?
          tedatum.text := trim (tedatum.text);
 
          if   tedatum.text <> ''
          then rec.datum := strtodate (tedatum.text)
          else
          begin
               beep;
               showmessage ('Das Datum ist ungültig! (Leeres Feld)');
               tedatum.setfocus;
               exit;
          end;
     except
          beep;
          showmessage ('Das Datum ist ungültig! ' + #13#13 + 'Es lautet: ' + tedatum.text);
          tedatum.setfocus;
          exit;
     end;
 
     try
          // Jahr korrekt?
          tejahr.text := trim (tejahr.text);
 
          if   tejahr.text = ''
          then tejahr.text := '0';
 
          if   strtoint (tejahr.text) <> 0
          then; // nur um festzustellen, daß numerische Eingabe vorliegt !
     except
          beep;
          showmessage ('Das Jahr ist ungültig');
          tejahr.setfocus;
          exit;
     end;
 
     // Wurde ein Format ausgewählt?
     if   liformat.ItemIndex = -1 then
     begin
          beep;
          showmessage ('Es wurde kein Format ausgewählt!');
          liformat.setfocus;
          exit;
	end;
 
     modalresult := mrok;
     close;                               
 
 
FormClose:
 
     us.EFVollbild := windowstate = wsmaximized;
     windowstate := wsnormal;
     us.EFPos := boundsrect;
     closeaction := caHide;
Könnte hier irgendwo der Fehler liegen?
Zuletzt geändert von Lori am So 6. Apr 2014, 15:15, insgesamt 1-mal geändert.
Grund: Highlighter

Patito
Beiträge: 203
Registriert: Di 22. Sep 2009, 13:08
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Showmodal

Beitrag von Patito »

Hm. Also mit ShowModal hatte ich unter Linux auch schon Probleme.
Bei mir hat z.B. ein TEdit ständig den Focus von einem TDrawGrid geklaut.

Die Ursache für sowas könnten aber auch irgendwelche Bugs oder "Features" in der speziellen
Linux-Distribution sein. Unter Windows hatte ich bei den Sachen die ich portiert habe praktisch keine Probleme.

Bei Dir kommt viel SetFocus vor. Ob es damit etwas zu tun hat?

Bei mir hat vermutlich der Windows-Manager immer unsinnig am Focus rumgepfusch.
Es wurde immer der Focus von einem readonly DrawGrid weggenommen und auf ein TEdit gesetzt
- warum auch immer - auf jeden Fall konnte man im Grid nicht mehr mit den Pfeiltasten scrollen...

wp_xyz
Beiträge: 5139
Registriert: Fr 8. Apr 2011, 09:01

Re: Showmodal

Beitrag von wp_xyz »

Das "Close" am Ende des btnOKClick muss raus. Wenn du ModalResult auf einen Wert <> mrNone setzt, wird das Formular automatisch geschlossen. Im Source code von TCustomForm steht aber auch

Code: Alles auswählen

 
procedure TCustomForm.Close;
var
  CloseAction: TCloseAction;
  IsMainForm: Boolean;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
  begin          
  ...
 
Das heißt, dass bei einem modalen Fenster ModalResult auf mrCancel zurückgesetzt wird, wenn du Close explizit aufrufst --> der Breakpoint nach ShowModal wird nie erreicht. Unklar ist mir noch, warum, der Debugger erst beim Programmende an die fragliche Stelle springt.

Folgende Punkte fallen mir noch auf:

In dem Code des 1.Postings erzeugst du das Formular mit dem Defaultnamen, so wie es automatisch erzeugt würde. Wird das Formular automatisch erzeugt? D.h., steht es bei den Projekt-Optionen unter "Formulare" in der linken Liste? Das wäre schlecht, weil du dir damit ein Speicherleck erzeugst, es wäre ja zweimal erzeugt worden, kann aber wegen des Namenskonflikts nur 1x freigegeben.

Im FormClose-Code ist die Verwendung von CloseAction := caHide unnötig: erstens ist das sowie der Default-Wert, und zweitens zerstörst du das Formular sowieso gleich durch Aufruf von Free.

HaseCaesar
Beiträge: 27
Registriert: Mi 2. Apr 2014, 09:47

Re: Showmodal

Beitrag von HaseCaesar »

wp_xyz hat geschrieben:Das "Close" am Ende des btnOKClick muss raus. Wenn du ModalResult auf einen Wert <> mrNone setzt, wird das Formular automatisch geschlossen. Im Source code von TCustomForm steht aber auch

Code: Alles auswählen

 
procedure TCustomForm.Close;
var
  CloseAction: TCloseAction;
  IsMainForm: Boolean;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
  begin          
  ...
 
Das heißt, dass bei einem modalen Fenster ModalResult auf mrCancel zurückgesetzt wird, wenn du Close explizit aufrufst --> der Breakpoint nach ShowModal wird nie erreicht. Unklar ist mir noch, warum, der Debugger erst beim Programmende an die fragliche Stelle springt.

Folgende Punkte fallen mir noch auf:

In dem Code des 1.Postings erzeugst du das Formular mit dem Defaultnamen, so wie es automatisch erzeugt würde. Wird das Formular automatisch erzeugt? D.h., steht es bei den Projekt-Optionen unter "Formulare" in der linken Liste? Das wäre schlecht, weil du dir damit ein Speicherleck erzeugst, es wäre ja zweimal erzeugt worden, kann aber wegen des Namenskonflikts nur 1x freigegeben.

Im FormClose-Code ist die Verwendung von CloseAction := caHide unnötig: erstens ist das sowie der Default-Wert, und zweitens zerstörst du das Formular sowieso gleich durch Aufruf von Free.
danke für den tipp. habe deinen rat befolgt. ERGEBNIS: Jetzt kann ich sowohl auf Abbruch als auch auf OK klicken - UND NICHTS GESCHIEHT! Das Formular schließt sich nicht mehr. Kann ja nicht normal sein, oder?

Was das automatische Erzeugen betrifft: Hier mal der Inhalt der Projekt-Datei:


program FilmDBNeu;

uses
Forms, Interfaces,
UFHaupt in 'UFHaupt.pas' {FHaupt};

{ $R *.RES}

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TFHaupt, FHaupt);
Application.Run;
end.


ist doch ok, oder?

wp_xyz
Beiträge: 5139
Registriert: Fr 8. Apr 2011, 09:01

Re: Showmodal

Beitrag von wp_xyz »

ModalResult des ok-Buttons = mrOK? ModalResult des Cancel-Buttons = mrCancel?
ist doch ok, oder?
ja. Aber da FKorrigieren eine globale Variable ist, solltest du sie nach dem Zerstören des Formulars noch auf nil setzen, oder gleich FreeAndNil(FKorrigieren) verwenden

Antworten