Einzelnen Beitrag anzeigen

Sankt Rochus

Registriert seit: 30. Nov 2012
15 Beiträge
 
#1

Formular modal öffnen

  Alt 4. Sep 2015, 10:28
Hallo,

ich bin eigentlich kein grober Neuling in Delphi und scheitere doch an den einfachsten Problemen, dank dieses neuen tollen FireMonkey-Frameworks...

Ich habe eine Formularklasse TfLabTokenMapping. Darin enthalten ist eine Klassenfunktion, die die Klasse instanziiert und das Formular modal anzeigen soll. Es handelt sich um einen Konfigurationsdialog, bei dem ein String mit Einstellungen (MappingList) und ein boolesches Result (False = Klick auf Abbrechen) zurückgegeben werden sollen. Die Klassenfunktion wird von einer Methode im Hauptformular mit einigen, hier im Detail unwichtigen Parametern aufgerufen.

Konkret geht es mir um den hier korrekten Aufruf von ShowModal(...) und bestenfalls noch um das Freigeben des Speichers. Ich habe zwei Varianten ausprobiert.

Variante 1: ShowModal mit anonymer Funktion aufrufen. Ich bin kein Freund davon, doch ist das wohl der von Embarcadero empfohlene Weg. Die Variablen aNewMappingList und Result können nicht direkt von der anonymen Funktion aufgenommen werden (Compilerfehler). Deshalb lege ich sie erst in lokale Variablen ab, die ich anschließend kopiere.

Delphi-Quellcode:
class function TfLabTokensMapping.ChangeMapping(aRequiredLabParams, aCurrentMappingList, aAllLabTokensWithDesc: string; out aNewMappingList: string): Boolean;
var
  fLabTokensMapping: TfLabTokensMapping;
  l_NewMappingList: string;
  l_Result: Boolean;
begin
  // Nur etwas initialisieren und eine Parameterprüfung
  Result := False;
  aNewMappingList := EmptyStr;
  if Length(Trim(aRequiredLabParams)) = 0 then
    Exit;

  // Das Formular erzeugen
  fLabTokensMapping := TfLabTokensMapping.Create(nil, aRequiredLabParams, aCurrentMappingList, aAllLabTokensWithDesc);

  // Das Formular anzeigen
  fLabTokensMapping.ShowModal(
    procedure(ModalResult: TModalResult)
    begin
      if (ModalResult = mrOk) then
      begin
        l_NewMappingList := fLabTokensMapping.Mapping;
        l_Result := True;
      end
      else
      begin
        l_Result := False;
      end;
    end);

  // Werte zurück geben
  aNewMappingList := l_NewMappingList;
  Result := l_Result;
end;
Problem dabei ist, dass ShowModal in diesem Fall nicht modal / blockierend ausgeführt wird. Frechheit von FireMonkey. Damit rattert mein Code durch und selbst die aufrufende Methode wird weiter fortgesetzt. Natürlich sind aNewMappingList und Result dann noch nicht gesetzt worden. Kann ich das Blockieren irgendwie erzwingen?

Variante 2: So, wie ich das aus der VCL gewohnt bin:

Delphi-Quellcode:
class function TfLabTokensMapping.ChangeMapping(aRequiredLabParams, aCurrentMappingList, aAllLabTokensWithDesc: string; out aNewMappingList: string): Boolean;
var
  fLabTokensMapping: TfLabTokensMapping;
  l_NewMappingList: string;
  l_Result: Boolean;
begin
  // Nor Initialisierungen und eine Parameterprüfung
  Result := False;
  aNewMappingList := EmptyStr;
  if Length(Trim(aRequiredLabParams)) = 0 then
    Exit;

  // Das Formular erzeugen
  fLabTokensMapping := TfLabTokensMapping.Create(nil, aRequiredLabParams, aCurrentMappingList, aAllLabTokensWithDesc);

  // Formular anzeigen und Ergebnis zurück geben
  if (fLabTokensMapping.ShowModal = mrOk) then
  begin
    aNewMappingList := fLabTokensMapping.Mapping;
    Result := True;
  end
  else
  begin
    Result := False;
  end;
end;
Jetzt blockiert ShowModal auch. Jedoch bekommen ich nun seltsames Verhalten nach Rückkehr zu meinem Hauptformular. Irgendwie scheinen einige Messages nicht mehr verarbeitet zu werden. Button-Klicks machen nichts mehr, Hover-Events und das Verschieben des Formulars funktionieren noch. Seltsam.

Das modale Fenster gebe ich übrigens in beiden Varianten per FormClose() frei:

Delphi-Quellcode:
procedure TfLabTokensMapping.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := TCloseAction.caFree;
end;
Was kann ich tun? Weiß irgendjemand Rat?

Vielen Dank schon einmal.
  Mit Zitat antworten Zitat