[Gelöst] ShowModal bringt Rechner zum hängen

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

[Gelöst] ShowModal bringt Rechner zum hängen

Beitrag von MacWomble »

Ich verwende Linux Mint 19.1 mit aktuellstem Lazarus und FPC.

Nun habe ich folgendes Problem:
Hinweis vorab: alle forms werden dynamisch erzeugt und nicht beim Programmstart erzeugt!

Modale Form1 ruft Form3 modal auf - das funtioniert

Modale Form1 ruft Form2 modal auf - soweit so gut...
dann ruft Form2 Form3 modal auf - System hängt, keine Eingaben mehr möglich, kein Programmabbruch möglich (auch nich mit kill Process).

Woran könnte das liegen? Kann man ShowModal eventuell nicht mehr als zwei mal hintereinander aufrufen?
Zuletzt geändert von MacWomble am Mi 9. Jan 2019, 08:28, insgesamt 1-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: ShowModal bringt Rechner zum hängen

Beitrag von Timm Thaler »

Was passiert denn mit Form3 vor dem zweiten Aufruf? Wird die geschlossen, wird die zerstört, wird die unsichtbar gemacht?

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: ShowModal bringt Rechner zum hängen

Beitrag von MacWomble »

Die Form 3 wird neu erzeugt. Das Problem tritt auch auf, wenn ich den ersten Schritt weg lasse.

Das Problem ist, dass ich mir dem Debugger nicht an die Stelle komme, wo es kracht.
In der Form3 gibt es eine Funktion BearbeiteForm3.

In dieser wird die Form3 createt und mit showmodal angezeigt sowie beim schließen wieder zerstört.
Im ersten Fall geht das wunderbar, im zweiten Fall (mit dem selben Aufruf) geht es nicht.

Der einzige Unterschied ist, dass eine weitere Form 'dazwischen' liegt.

Ich komme beim tracen bis zu Form3.formshow. Danach geht das Programm in customform.inc,

Code: Alles auswählen

procedure TCustomForm.CMShowingChanged(var Message: TLMessage);
begin
  try
    if Showing then
      DoShow
    else
      DoHide;
  except
    if not HandleShowHideException then
      raise;
  end;
  inherited CMShowingChanged(Message);
end;   


Assembler (erscheint nach Abarbeiten der Zeile Inherited ...:
000000000043208A eb49 jmp 0x4320d5 <SYSTEM$_$TOBJECT_$__$$_DISPATCH$formal+245>

wenn ich dann weiter durch das Pogramm steppe:

Code: Alles auswählen

 
procedure TCustomForm.UpdateShowing;
begin
  if csLoading in ComponentState then exit;
  {$IF defined(CHECK_POSITION) or defined(VerboseFormUpdateShowing) or defined(VerboseShowing)}
  DebugLn(['[TCustomForm.UpdateShowing] START ',DbgSName(Self),' Pos=',Left,',',Top,' Visible=',Visible,' Showing=',Showing]);
  {$ENDIF}
  // If the form is about to show, calculate its metrics
  if Visible and (not (csDestroying in ComponentState)) then
  begin
    if not (csDesigning in ComponentState) then
      MoveToDefaultPosition;
    if (fsFirstShow in FFormState) then
    begin
      Exclude(FFormState, fsFirstShow);
      DoFirstShow;
    end;
  end;
  {$IF defined(CHECK_POSITION) or defined(VerboseFormUpdateShowing) or defined(VerboseShowing)}
  DebugLn(['[TCustomForm.UpdateShowing] calling inherited  ',dbgsname(Self),' Pos=',Left,',',Top]);
  {$ENDIF}
  inherited UpdateShowing;
  {$IF defined(CHECK_POSITION) or defined(VerboseFormUpdateShowing) or defined(VerboseShowing)}
  DebugLn(['[TCustomForm.UpdateShowing] activating  ',dbgsname(Self),' Pos=',Left,',',Top]);
  {$ENDIF}
  // activate focus if visible
  if Showing and (not (csDestroying in ComponentState)) then
  begin
    if (not Assigned(ActiveControl)) and (not (csDesigning in ComponentState)) and (Parent=nil) then
    begin
      // automatically choose a control to focus
      {$IFDEF VerboseFocus}
      DebugLn('TCustomForm.CreateWnd ',DbgSName(Self),' Set ActiveControl := ',DbgSName(FindDefaultForActiveControl));
      {$ENDIF}
      ActiveControl := FindDefaultForActiveControl;
    end;
    if (Parent=nil) and Assigned(ActiveControl) and
       ActiveControl.HandleAllocated and ActiveControl.CanFocus and
       ([csLoading, csDestroying, csDesigning] * ComponentState = []) then
    begin
      {$IFDEF VerboseFocus}
      DebugLn('TCustomForm.CreateWnd A ',DbgSName(Self),' FActiveControl=',DbgSName(FActiveControl));
      {$ENDIF}
      LCLIntf.SetFocus(ActiveControl.Handle);      //    <==== Nach dieser Zeile hängt alles
    end;
    UpdateShowInTaskBar;
  end;
end;             
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

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

Re: ShowModal bringt Rechner zum hängen

Beitrag von wp_xyz »

MacWomble hat geschrieben:In der Form3 gibt es eine Funktion BearbeiteForm3.
In dieser wird die Form3 createt und mit showmodal angezeigt sowie beim schließen wieder zerstört.

Das kann eigentlich nicht funktionieren (es sei denn, BearbeiteForm3 ist eine Klassen-Funktion): Wie kann man die Methode eines Formulars aufrufen, das es noch gar nicht gibt?

Sieh dir das beigefügte Projekt an, das demonstriert, dass der kaskadierte Aufruf von ShowModal keinen Absturz bewirkt.
Dateianhänge
MultipleShowModal.zip
(3.09 KiB) 118-mal heruntergeladen

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: ShowModal bringt Rechner zum hängen

Beitrag von MacWomble »

Falsch ausgedrückt: In der Unit der Form3 (bzw. TFrmAdresse)....

Code: Alles auswählen

...
 
function BearbeiteAdresse(IDAdresse: integer; Neu: boolean): boolean;
var
  Suchtext: string;
  LastRec: integer;
  F: TfrmAdresse;
begin
  DoSave := False;
  with dtmAdressen do
  begin
 
    F := TfrmAdresse.Create(nil);
 
    F.memAdressNotiz.Text := qryAdresse.FieldByName('adr_notiz').AsString;
    try
      F.ShowModal;
      if DoSave then
      begin
        if qryAdresse.State = dsEdit then
        begin
          qryAdresse.FieldByName('adr_notiz').AsString := F.memAdressNotiz.Text;
          qryAdresse.ApplyUpdates;
        end;
        qryAdressListe.Refresh;
        qryAdressListe.Locate('idadresse', qryAdresse.FieldByName('idadresse').AsInteger, []);
        Result := True;
      end
      else
      begin
        qryAdresse.CancelUpdates;
        Result := False;
      end;
    finally
      FreeAndNil(F);
    end;
  end;
end;
 
{ TfrmAdresse }
 
procedure TfrmAdresse.btnSpeichernClick(Sender: TObject);
begin
  DoSave := True;
  Close;
end;
          ....                                 
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: ShowModal bringt Rechner zum hängen

Beitrag von MacWomble »

OK, der Fehler muss eine andere Ursache haben. Ich habe das gleiche Konstrukt zwei mal im Projekt.
Einmal für Artikelverwaltung , dort funktioniert es, ein mal für Adressverwaltung, wo es zum Problem kommt.
Außer den unterschiedlichen Formularfeldern und der angebundenen Datenquellen gibt es keinen offensichtlichen Unterschied.
Es kann m.E. nicht an den Feldern oder Daten liegen, das habe ich durch den Austausch der Form3 mehrfach versucht.
Auch funktioniert die form3 ja überall, nur nicht in diesem einen speziellen Fall.
Die Forms haben auch unterschiedliche Namen, so dass auch eine Überschneidung hier ausgeschlossen werden kann.
Ich meine mich zu erinnern, dass das ganze schon mal funktioniert hatte, bin mir aber nicht ganz sicher.

Wie könnte ich hier den Fehler weiter eingrenzen? Der Debugger zeigt mir nichts wirklich sinnvolles an.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Lemmy
Beiträge: 57
Registriert: Do 23. Feb 2017, 06:18

Re: ShowModal bringt Rechner zum hängen

Beitrag von Lemmy »

Servus,

sicher, dass das Form3 nicht HINTER Form2 liegt? D.h. das programm funktioniert, du siehst es aber nicht :-)

Grüße

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: ShowModal bringt Rechner zum hängen

Beitrag von MacWomble »

Ja, habe ich getestet. Es hängt ja auch nicht nur die Anwendung, sondern der Desktop komplett. Die Form wird definitv nicht gezeichnet.
Es liegt aber auch ziemlich sicher nicht an der Form ... bin ratlos.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Lemmy
Beiträge: 57
Registriert: Do 23. Feb 2017, 06:18

Re: ShowModal bringt Rechner zum hängen

Beitrag von Lemmy »

auch schon mal den Produktivcode aus der Form entfernt (auskommentiert)? Speziell in den Events.....

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: ShowModal bringt Rechner zum hängen

Beitrag von MacWomble »

Ja, das habe ich auch bereits versucht.
Wie schon erwähnt, glaube ich nicht an einen Fehler in der Form. Diese funktioniert an anderen Stellen - und wenn ich sie durch andere funktionierende Forms ersetze, geht es auch nicht.
Es kann aber auch nicht am Aufruf liegen da dieser an allen Stellen gleich ist. Irgendetwas dummes muss sich hier im Hintergrund ereignen, aber ich komme nicht an die Infos. Alles was ich erkennen kann ist oben gepostet.
Irgendwie passiert es wohl genau in dem Moment, in welchem die Form tatsächlich gezeichnet werden soll ...

Ich habe mich allerdings getäuscht, was die Tiefe angeht. Dies ist der einzige Fall, wo die Form über drei Forms geht:

Funktioniert nicht (die letzte - 4. - Form wird nicht angezeigt, der Prozess hängt sich auf und kann auch mit kill nicht beendet werden!:

frmAktenListe - frmAkteErfassen - FrmAdressAuswahlListe - FrmAdresseErfassen
oder
frmAuftragsListe - frmAuftragErfassen - FrmAdressAuswahlListe - FrmAdresseErfassen
oder
frmAuftragsListe - frmAuftragErfassen - FrmAdressAuswahlListe - FrmKontaktErfassen
oder (Sinnfrei)
frmAktenListe - frmAkteErfassen - FrmAdressAuswahlListe - FrmAdresseArten

Funktioniert;

FrmAdressListe - FrmAdresseErfassen
oder
FrmAdressListe - FrmAdresseErfassen - FrmAdressArten
jedoch auch (Sinnfrei):
FrmAdressListe - FrmAdresseErfassen - FrmKontaktdaten - FrmAdresseArten (hier geht auch die 4. Form!)

- Die FrmAdressListe wie auch die AdressAuswahlListe sind im Prinzip identisch ...
- Alle Frm funktionieren für sich problemlos ...
- Es scheint nur beim Aufruf aus FrmAdressAuswahlListe zu diesem Phänomen zu kommen ...

Die FrmAdressAuswahlListe enthält im Prinzip nur zwei dbGrid und ein paar Buttons, welche Actions aus einer Actionlist aufrufen (z.B. eben BearbeiteAdresse).
Eigentlich kann man hier nicht wirklich etwas falsch machen.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

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

Re: ShowModal bringt Rechner zum hängen

Beitrag von wp_xyz »

Am Code im Post vom 6.1. 14:24 fällt mir auf, dass die offenbar eine Änderung in einen TDataset schreiben willst, aber nirgendwo sehe ich ein .Post. Im folgenden Code-Ausschnitt noch ein paar weitere Kommentare, die aber genauso gut Unsinn sein können, weil ich deinen restlichen Code nicht kenne, insbesondere nicht, was in TfrmAdresse passiert.

Code: Alles auswählen

function BearbeiteAdresse(IDAdresse: integer; Neu: boolean): boolean;
var
  Suchtext: string;
  LastRec: integer;
  F: TfrmAdresse;
begin
  DoSave := False;
  with dtmAdressen do
  begin
 
    F := TfrmAdresse.Create(nil);
 
    F.memAdressNotiz.Text := qryAdresse.FieldByName('adr_notiz').AsString// Das sollte eigentlich hinter dem "try" stehen. Was, wenn F nicht erzeugt werden konnte, also nil ist?
    try
      F.ShowModal;
      if DoSave then
      begin
        if qryAdresse.State = dsEdit then     // was wenn .State = dsInsert? Besser: "if qryAdresse.State in dsEditStates"
        begin
          qryAdresse.FieldByName('adr_notiz').AsString := F.memAdressNotiz.Text;
          qryAdresse.Post;              // <---- NEU
          qryAdresse.ApplyUpdates;
        end;
        qryAdressListe.Refresh;
        qryAdressListe.Locate('idadresse', qryAdresse.FieldByName('idadresse').AsInteger, []);
        Result := True;
      end
      else
      begin
        qryAdresse.CancelUpdates;   // wieso das denn? Du hast doch nichts geschrieben. Evtl. fehlt noch ein qryAdresse.Cancel.
        Result := False;
      end;
    finally
      FreeAndNil(F);
    end;
  end;
end;

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: ShowModal bringt Rechner zum hängen

Beitrag von MacWomble »

Du hast recht, da habe ich wirklich Unstimmigkeiten drin - Danke für die Hinweise! Ich werde versuchen, mich zu bessern :oops:
P.S: dsEditState muss dsEditModes lauten.

Aber mit meinem eigentlichen Problem hat dies nichts zu tun.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: ShowModal bringt Rechner zum hängen

Beitrag von af0815 »

Ganz dumme Fragen:
a) Tritt das auch ohne Debugger auf ?
b) Wenn ja, steht was auf der Konsole, wenn das Prg von der Konsole aus gestartet wird ?

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: ShowModal bringt Rechner zum hängen

Beitrag von MacWomble »

Es gibt keine dummen Fragen ...

1. Der Fehler tritt auch im Release auf
2. Keine Ausgabe in der Console (weder in Debug noch Release)

Zu 2.: Wie oben geschrieben bleibt einfach alles stehen:

Der Button, welcher die Form startet bleibt gedrückt! Alles wird abgearbeitet bis zum Ausführen von "LCLIntf.SetFocus(ActiveControl.Handle); " auf der neuen (noch nicht sichtbaren) Form, dann ist alles vorbei.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Lemmy
Beiträge: 57
Registriert: Do 23. Feb 2017, 06:18

Re: ShowModal bringt Rechner zum hängen

Beitrag von Lemmy »

kannst Du das Form mal in eine leere Anwendung aufnehmen und von dort aus aufrufen?

Antworten