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.