J'ai un formulaire principal (parent) MDI et une forme d'enfant MDI. Je crée l'enfant à l'exécution comme ceci: étapes pour reproduire l'erreur: la ligne sur laquelle l'erreur apparaît est sur le formulaire enfant: p>
Je démarre l'application, j'appuie sur le bouton pour créer l'enfant, j'appuie sur le bouton "X" du formulaire "X" sur le formulaire principal (parent) pour fermer l'application et je reçois un "Impossible de créer un formulaire. Aucun formulaire MDI n'est actuellement actif" Erreur. / p> procedure TFrmDereplic.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TFrmDereplic.FormDestroy(Sender: TObject);
VAR MyIniFile: TCubicIniFile;
begin
MyIniFile:= TCubicIniFile.Create(AppINIFile);
TRY
with MyIniFile DO
begin
if WindowState<> wsMaximized then
begin
// save form's screen pos
...
end;
WriteInteger ('Dereplicator', 'fltExtensions', fltExtensions.ItemIndex); <----- HERE
FINALLY
FreeAndNil(MyIniFile);
END;
end;
3 Réponses :
Je regarde sur certains sites Web et je viens de trouver le problème. On dirait qu'il est de préférence que le propriétaire soit défini sur l'application, au lieu de la forme principale. Remy Lebeau suggère que le vrai problème est dans l'Ondestroy de la forme de l'enfant. Il n'y a pas de poignée valide à la fenêtre qui contient le filtre puis l'Ondestroy est appelé. Ainsi, la modification de l'ordre de destruction donne une chance à TfrmderePlic.ondestroy d'exécuter correctement. P>
Donc, voici la solution: p>
frmdereplic: =
Tfrmdereplic.create (application); p>
blockQuote>
ou p>
Ne pas enregistrer les propriétés du formulaire dans
OnDestroy p>
blockQuote>
Le second nécessite peu de lignes de code supplémentaires car l'on close n'est même pas toujours appelée.
Cela a été extrait de Delphi Help: p>
Remarque: lorsque l'application se ferme
bas, la forme principale reçoit un
Événement surclose, mais tous les formulaires enfants ne reçoivent pas l'événement OnClose. P>
blockQuote>
Si vous utilisez une application.Terminate, alors onCloseQuery et OnClose ne sera pas appelé. Idem pour arrêter (mais ... c'est beaucoup trop extrême, non?). P>
Si le code que vous avez fourni dans votre question est le vrai que je suppose que l'erreur est dans cette ligne: Je n'ai jamais essayé cela et je ne sais pas si le compilateur achète vraiment Il (je ne peux pas le tester maintenant), mais vous essayez de définir une classe comme propriétaire de la forme enfant MDI. Au lieu de cela, vous devriez faire soit P> FrmDereplic:= TFrmDereplic.Create(self);
L'OP est venu à cette conclusion trois heures avant de faire votre message.
@Andreas - Je voulais marquer mon poteau comme résolu mais Stackoverflow me fait attendre 2 jours. Quoi qu'il en soit, c'est bien que d'autres personnes confirment ma solution. Cela signifie que c'est bon.
@ Vicens - désolé. C'est en effet la forme principale au lieu de Tmainform. J'ai entré l'erreur lorsque j'ai saisi le code. Dans mon code, le formulaire a un nom différent. J'ai changé de nom sur Mainform pour rendre le code plus facile à comprendre (formulaire principal = le parent de la forme enfant). Encore pardon. Veuillez noter que soi-même ne fonctionnera pas !! Il est en fait équivalent à mon code d'origine (buggy). Pourquoi? Parce que soi-même = mainforme.
@Andreas - Oui, tu as raison. Je voulais simplement clarifier que si le code fourni était le réel, l'erreur était probablement dans cette ligne de code, en plus de donner une alternative à la définition de la demande en tant que propriétaire du formulaire enfant MDI. Accordé, peut-être qu'un commentaire aurait suffi. :-)
@Altar, je n'ai pas accès à ma copie Delphi à la maison mais je pourrais jurer que vous devriez pouvoir définir le formulaire principal en tant que propriétaire du formulaire enfant MDI tant qu'il est déclaré comme MDI lui-même. Je vais l'essayer demain au travail.
@Vicens - vous avez raison. Définir la forme principale car le propriétaire est correct mais comme il vient d'expliquer ci-dessus ne fonctionne toujours pas. Utiliser l'application comme le propriétaire est meilleur.
L'erreur se produit lors de la lecture de la propriété Enregistrement de vos données INI dans le formulaire fltextensions.itemindex code> car il nécessite fltextensions code> pour avoir un HWND, qui nécessite sa forme de parent TFRMDerePlic d'avoir une HWND, qui nécessite la Leform de projet pour avoir un HWND. Mais l'application est dans un état d'arrêt et le formal MainForm ne peut plus affecter sa HWND, de sorte que TFRMDEREPLIC augmente une exception lorsqu'il ne peut pas obtenir un HWND pour lui-même. P>
OnDestroy code> est trop tard. Vous devez plutôt que l'événement OnClose code> à la place. P>
Mais on ongled est ignoré dans certaines situations. Ce qui signifie que les données ne seront pas enregistrées sur le disque! Ma mise en œuvre actuelle fonctionne. Est-ce faux? Puis-je l'utiliser tel quel? Je suppose que l'utilisation de la demande en tant que propriétaire de ce formulaire change la séquence de destruction. Cela donne une chance à TFRMDerePlic d'exécuter correctement OnDestroy.
OnClose est appelé lors de la fermeture de l'application par la plupart des moyens - x Bouton x sur la fenêtre, Tform.Close (), Application.Terminate (), etc. Mais oui, il y a des situations où l'on ne l'appelle pas toujours, mais ces conditions peuvent être traité séparément. Vous pouvez refactoriser votre code d'économie dans sa propre fonction que vous pouvez appeler de plusieurs endroits en cas de besoin. Quant à la raison pour laquelle le code lui-même est faux, j'ai déjà expliqué que - OnDestroy est généralement trop tard pour accéder aux valeurs de propriété basées sur HWND, comme l'itemindex. Définir l'applicaton comme le propriétaire a simplement permis à l'enfant MDI d'être détruit avant le formal principal.
«Quant à la raison pour laquelle le code lui-même a tort, j'ai déjà expliqué que» - Désolé, je parlais du nouveau code où je l'ai réparé en définissant la demande (au lieu de MainForm) en tant que propriétaire. Si cette affectation est valide, je préférerais l'utiliser au lieu d'abandonner sur l'oncle.
L'aide DELPHI 7 indique: "Lorsque l'application s'arrête, la forme principale reçoit un événement OnClose, mais les formulaires enfants ne reçoivent pas l'événement OnClose"
C'est vrai. Les formulaires enfants MDI ne font pas feu à Thier OnClose CODE> Événement lorsque l'événement CODE> OnClose de MainForm '/ code> est viré. Toutefois, ils incendient leur code> événement code> lorsque l'événement ONCLOSEQUERY CODE> est tiré.
Affectation de l'application Au fur et à mesure que le propriétaire permet de détruire le formulaire enfant avant la forme principale plutôt que par la suite, car TComponent détruit ses objets appartenant à l'ordre opposé à celui qu'ils ont été créés.