Daten aus modalen Formularen abrufen

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Daten aus Formularen abrufen


Modale Formulare enthalten wie nichtmodale Formulare oft Informationen, die in anderen Fenstern benötigt werden. In der einfachsten Form ruft Formular A das modale Formular B auf. Nach dem Schließen von Formular B muss Formular A wissen, welche Aktionen der Benutzer in Formular B durchgeführt hat, da das weitere Vorgehen davon abhängt. Befindet sich Formular B noch im Speicher, können wie beim nichtmodalen Formular im letzten Beispiel die Eigenschaften und Elementfunktionen verwendet werden. Wie können aber Werte abgerufen werden, wenn Formular B beim Schließen aus dem Speicher entfernt wird? Da ein Formular keinen expliziten Rückgabewert hat, müssen die benötigten Informationen vor dem Freigeben irgendwo gespeichert werden.

Sehen Sie sich dazu die folgende Version von ColorForm an. Das Formular ist diesmal modal und wird folgendermaßen deklariert:

TColorForm = class(TForm)
  ColorListBox:TListBox;
  SelectButton: TButton;
  CancelButton: TButton;
  procedure CancelButtonClick(Sender: TObject);
  procedure SelectButtonClick(Sender: TObject);
private
  FColor: Pointer;
public
  constructor CreateWithColor(Value: Pointer; Owner: TComponent);
end;
class TColorForm : public TForm {
__published: // IDE-managed Components

	TListBox *ColorListBox;
	TButton *SelectButton;
	TButton *CancelButton;

	void __fastcall CancelButtonClick(TObject *Sender);
	void __fastcall SelectButtonClick(TObject *Sender);

private: // User declarations

	String* curColor;

public: // User declarations

	virtual __fastcall TColorForm(TComponent* Owner);
	virtual __fastcall TColorForm(String* s, TComponent* Owner);
};

Das Formular enthält ein Listenfeld (ColorListBox) mit einer Auswahl verschiedener Farben. Beim Klicken auf die Schaltfläche SelectButton wird der aktuelle Farbwert gespeichert und das Formular geschlossen. Mit der Schaltfläche CancelButton wird das Formular geschlossen, ohne den Wert zu speichern.

Beachten Sie, dass ein zweiter Konstruktor vorhanden ist, dem ein Pointer-Argument übergeben wird. Dieser Zeiger verweist auf einen String, der dem aufrufenden Formular ColorForm bekannt ist. Der Konstruktor ist folgendermaßen implementiert:

constructor TColorForm(Value: Pointer; Owner: TComponent);
begin
  FColor := Value;
  String(FColor^) := '';
end;
void__fastcall TColorForm::TColorForm(String* s, TComponent* Owner)
    : TForm(Owner) {
    curColor = s;
    *curColor = "";
}

Der Konstruktor speichert den Zeiger im private-Datenelement FColor und initialisiert den String mit einer leeren Zeichenfolge.

Anmerkung: Dieser Konstruktor kann nur verwendet werden, wenn das Formular explizit erstellt und nicht beim Programmstart automatisch instantiiert wird und nicht beim Programmstart automatisch instantiiert wird. Informationen hierzu finden Sie unter Die Formularerstellung im Speicher steuern.

In der Anwendung wählt der Benutzer eine Farbe aus der Liste und klickt auf SelectButton, um die Auswahl zu speichern und das Formular zu schließen. Der Quelltext der OnClick-Ereignisbehandlungsroutine für SelectButton sieht folgendermaßen aus:

procedure TColorForm.SelectButtonClick(Sender: TObject);
begin
  with ColorListBox do
    if ItemIndex >= 0 then
      String(FColor^) := ColorListBox.Items[ItemIndex];
  end;
  Close;
end;
void __fastcall TColorForm::SelectButtonClick(TObject *Sender) {
    int index = ColorListBox->ItemIndex;
    if (index >= 0)
        * curColor = ColorListBox->Items->Strings[index];
    Close();
}

Diese Ereignisbehandlungsroutine speichert den Namen der ausgewählten Farbe in dem String, auf den der an den Konstruktor übergebene Zeiger verweist.

Damit ColorForm richtig verwendet werden kann, muss das aufrufende Formular dem Konstruktor einen Zeiger auf einen vorhandenen String übergeben. Nehmen wir an, ColorForm wird vom Formular ResultsForm in Reaktion auf einen Klick auf die Schaltfläche UpdateButton instantiiert. Die Ereignisbehandlungsroutine könnte dann folgendermaßen aussehen:

procedure TResultsForm.UpdateButtonClick(Sender: TObject);
var
  MainColor: String;
begin
  GetColor(Addr(MainColor));
  if MainColor <> '' then
    {do something with the MainColor string}
  else
    {do something else because no color was picked}
end;

procedure GetColor(PColor: Pointer);
begin
  ColorForm := TColorForm.CreateWithColor(PColor, Self);
  ColorForm.ShowModal;
  ColorForm.Free;
end;
void __fastcall TResultsForm::UpdateButtonClick(TObject *Sender) {
	String s;
	GetColor(&s);
	if (s != "") {
		// do something with the color name string
	}
	else {
		// do something else because no color was picked
	}
}

// ---------------------------------------------------------------------
void TResultsForm::GetColor(String *s) {
	ColorForm = new TColorForm(s, this);
	ColorForm->ShowModal();
	delete ColorForm;
	ColorForm = 0; // NULL the pointer
}

In der Routine UpdateButtonClick wird zuerst der String MainColor erstellt. Die Adresse dieses Strings wird an die Funktion GetColor übergeben, in der das Formular ColorForm erstellt und der Zeiger auf MainColor als Argument an den Konstruktor übergeben wird. Obwohl ColorForm nach dem Schließen sofort wieder freigegeben wird, ist der gewählte Farbname noch in MainColor gespeichert, wenn im Formular eine Farbe ausgewählt wurde. Andernfalls enthält MainColor einen leeren String, woran eindeutig zu erkennen ist, dass der Benutzer ColorForm geschlossen hat, ohne eine Farbe auszuwählen.

In diesem Beispiel werden die Informationen aus dem modalen Formular in einer String-Variablen abgelegt. Natürlich können bei Bedarf auch komplexere Datenstrukturen oder Objekte verwendet werden. Sie sollten aber immer eine Möglichkeit vorsehen, dem aufrufenden Formular mitzuteilen, dass das modale Formular ohne eine Änderung oder Auswahl durch den Benutzer geschlossen wurde (indem Sie MainColor beispielsweise einen leeren String als Standardwert zuweisen).

Siehe auch