6
votes

Ouvrir et fermer le formulaire VCL

En ce moment, j'ai 2 formulaires. Sur Form1, j'ouvre Form2 comme ceci:

procedure TForm2.cancelBtnClick(Sender: TObject);
begin
  Form2.Close;
end;`


0 commentaires

5 Réponses :


8
votes

Étant donné que le formulaire se présente de manière modale la solution correcte consiste à définir modalresult: = MRCancel dans votre bouton, cliquez sur le gestionnaire. Le raccourci consiste à définir la propriété modalresult du bouton sur MRCancel , puis vous n'avez même pas besoin du gestionnaire d'événements.


Notez que votre formulaire est être créé de manière incorrecte. Vous passez la variable non attribuée form2 comme paramètre propriétaire sur le constructeur. Je m'attends à ce que ce soit la cause de la violation d'accès.

Vous devez passer une autre forme, application ou nil , par exemple. En fait, dans ce cas, vous pouvez également passer à NIL afin que le code soit lu: xxx

Si vous passez un propriétaire, le formulaire sera détruit lorsque le propriétaire est détruit. Puisque vous la détruisez vous-même, vous n'avez pas besoin de passer un propriétaire.

qui dit, il est parfois utile de définir le propriétaire, par exemple si vous utilisez l'une des la position < / Code> Valeurs de propriété qui définit la position du formulaire en fonction de la position du propriétaire. Si oui, alors je recommande de passer auto dans cette instance qui est une référence d'objet tform1 .


0 commentaires

18
votes

La manière habituelle de le faire est de faire xxx

et, si tform2 contient un bouton OK, cela devrait avoir le modalresult Propriété définie sur mrak au moment de la conception. Utilisez l'inspecteur d'objets pour définir ceci. Vous souhaitez probablement aussi définir par défaut sur vrai . Maintenant, vous pouvez "cliquer" le bouton OK en appuyant sur la touche Entrée de votre clavier!

De plus, s'il y a un bouton Annuler dans la boîte de dialogue, cela devrait avoir modalresult défini Pour MRCancel et Annuler défini sur true . Maintenant, vous pouvez "cliquer" le bouton Annuler en appuyant sur la touche d'échappement de votre clavier!

Un bouton avec un modalresult Fermera automatiquement une boîte de dialogue modale.


7 commentaires

@ Jörn: "devrait" est un mot assez fort. Mais vous avez définitivement «pourrait» utiliser nil comme propriétaire.


@Andreas: Lorsqu'un propriétaire est passé au constructeur, c'est le propriétaire qui devrait être responsable de la libération du composant. Si le propriétaire est omis, l'exécution du constructeur et du destructeur sera plus rapide, car le propriétaire n'a pas besoin de maintenir la propriété du composant.


... suite: le propriétaire itière en fait à tous ses composants appartenant à la méthode créée et dans la méthode libre pour maintenir la propriété. C'est à dire. Que si vous passez de l'application en tant que propriétaire, le constructeur itération de toutes les composantes de chaque formulaire appartenant à l'application lors de la création et de la gratuité. Essayez de mesurer la création de 1000 composants avec Nil VS Self / Application et voir la différence ...


... suite: Un autre problème se pose si le propriétaire est libéré avant de libérer le composant Int-Th de Block (par exemple, un utilisateur ferme le formulaire). Le propriétaire libérera ensuite tous les articles appartenant, y compris celui que vous venez de créer. Vous obtiendrez probablement un AV dans le bloc enfin lorsque vous essayez de libérer le composant déjà libéré.


@ Jörn: Oui, je sais tout ça. Je ne pense pas que la différence de performance est aussi importante. Vous avez rarement plus d'une forme modale à la fois (pas mille!). Et sûrement il est assez improbable que tform1 soit libéré alors que le tform2 est modal ?!


@Andreas, je suis totalement d'accord dans ce cas, bien sûr :) et oui, ce problème est plus important pour les composants que les formes - en particulier les models ... J'aime juste être cohérent partout.


@Andreasrejbrand - Vous êtes l'un des meilleurs gars de Delphi Favoris sur l'ensemble de l'Internet. Merci d'avoir fait mieux le monde Delphes. J'espère que tu iras mieux bientôt!!!!!!!



2
votes

Les deux autres réponses discutent d'autres moyens de résoudre votre problème.

Je vais souligner la cause du problème.

Vous avez deux variables nommées form2. L'une contient la forme et l'autre est ininitialisée la plus probable nulle. La cause de l'A / V est parce que vous accédez à la variable NIL.

Lorsque vous travaillez avec une classe, vous devez éviter d'utiliser le nom de la variable de la classe, vous pouvez faire référence aux membres directement tels que l'appelant Fermer; sans référencer la variable. Pour garder les choses clairs, vous pouvez également le préfixer avec auto. remplacer form2.close; avec self.close;


2 commentaires

Si Form2 était nulle lorsque le constructeur a été appelé, il n'y aurait aucune erreur.


Il y a deux sections de code. Form2 dans la deuxième section du code n'a pas pu être la même variable. Je soupçonne que la variable globale créée par défaut.



1
votes

Dans votre deuxième code, vous êtes déjà dans le formulaire 2, vous devez donc seulement faire

procedure TForm2.cancelBtnClick(Sender: TObject);
begin
  Close;
end;


0 commentaires

1
votes

Je ne sais pas si vous avez déjà résolu cette question ou créé un nouveau code pour éviter le problème, mais ce que je pense se passe (et vous n'avez pas montré que tout votre code pour confirmer) est que vous avez créé un mauvais code sur l'événement principal de la forme principale Onactivate.

Lorsque vous quittez la deuxième forme, vous revenez à votre relève de la forme principale et il "Agit" à nouveau. Vous avez probablement manipulé un objet qui n'existe plus.


1 commentaires

Je vais vous donner un point chaque fois que je verrai votre nom. Je l'aime!!!! (Donc +1 ici).