Récupération des données des fiches modales

De RAD Studio
Aller à : navigation, rechercher

Remonter à Récupération des données des fiches


Tout comme les fiches non modales, les fiches modales contiennent souvent des informations nécessaires à d'autres fiches. Dans le cas de figure la plus classique, une fiche A lance la fiche modale B. Lors de la fermeture de B, la fiche A a besoin de savoir ce que l'utilisateur a fait dans la fiche B pour décider comment poursuivre les traitements de la fiche A. Si la fiche B est toujours en mémoire, il est possible de l'interroger via ses propriétés et ses fonctions membres tout comme les fiches non modales de l'exemple précédent. Mais comment faire si la fiche B est retirée de la mémoire une fois fermée ? Comme une fiche ne renvoie pas explicitement de valeur, il est nécessaire de préserver les informations importantes de la fiche avant de la détruire.

Pour illustrer cette manière de procéder, considérez une version modifiée de la fiche ColorForm conçue comme une fiche modale. Sa classe est déclarée de la manière suivante :

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);
};

La fiche contient une boîte liste nommée ColorListBox contenant une liste de noms de couleur. Quand il est choisi, le bouton nommé SelectButton mémorise le nom de la couleur sélectionnée dans ColorListBox puis ferme la fiche. CancelButton est un bouton qui ferme simplement la fiche.

Remarquez l'ajout à la déclaration de la classe d'un constructeur défini par l'utilisateur qui attend un argument Pointer. Normalement, ce paramètre Pointer pointe sur une chaîne gérée par la fiche qui déclenche ColorForm. Ce constructeur a l'implémentation suivante :

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 = "";
}

Le constructeur enregistre le pointeur dans une donnée membre privée FColor et initialise la chaîne avec une chaîne vide.

Remarque : Pour utiliser ce constructeur défini par l'utilisateur, la fiche doit être créée explicitement. Ce ne peut pas être une fiche auto-créée au démarrage de l'application. Pour plus d'informations, voir Contrôle quand les fiches résident en mémoire.

Dans l'application, l'utilisateur sélectionne une couleur dans la boîte liste puis clique sur le bouton SelectButton pour enregistrer son choix et fermer la fiche. Le gestionnaire d'événement OnClick du bouton SelectButton doit avoir la forme suivante :

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();
}

Remarquez comment le gestionnaire d’événement stocke le nom de couleur sélectionné dans la chaîne référencée par le pointeur qui a été transmise au constructeur.

Pratiquement, pour utiliser ColorForm, la fiche appelante doit transmettre au constructeur un pointeur sur une chaîne existante. Supposons par exemple que ColorForm est instanciée par une fiche appelée ResultsForm en réponse au choix d'un bouton de ResultsForm nommé UpdateButton. Le gestionnaire d'événement de ce bouton doit avoir la forme suivante :

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
}

UpdateButtonClick crée une chaîne nommée MainColor. L'adresse de MainColor est transmise à la fonction GetColor qui crée ColorForm, qui crée ColorForm est fermée, elle est détruite mais le nom de la couleur sélectionnée, s'il y en a une, est préservé dans MainColor. Sinon, MainColor contient une chaîne vide, ce qui indique clairement que l'utilisateur est sorti de ColorForm sans sélectionner une couleur.

Cet exemple utilise une variable chaîne pour stocker des informations provenant de la fiche modale. Il est possible d'utiliser des objets plus complexes en fonction de vos besoins. N'oubliez jamais qu'il faut laisser à la fiche appelante un moyen de savoir que la fiche modale a été fermée sans modification, ni sélection (dans l'exemple précédent en attribuant par défaut à MainColor une chaîne vide).

Voir aussi