Je veux laisser l'utilisateur de créer plusieurs instances du même formulaire (appelons-le formulaire1 qui est une forme d'enfant MDI). J'ai donc deux procédures comme celle-ci où je crée les formulaires.
procedure MyProcedure1; // procedure 2 is similar. it also has a var called MyFrm var MyFrm: TFrm1; begin ... MyFrm:= TFrm1.create(MainForm); MyFrm.BringToFront; MyFrm.LoadFromFile(someFile); end;
4 Réponses :
Assurez-vous que myfrm.name code> est le même pour les deux instances ... p>
myfrm.name code> est unique ... p>
Delphi attribue automatiquement des noms uniques à des formulaires créés de manière dynamique.
Le message est causé car chaque formulaire doit être nommé de manière unique.
Lorsque vous créez un formulaire deux fois, vous devez vous assurer que chaque instance a un nom unique, ou définir le nom sur une chaîne vide. Ce dernier est également l'affaire lors de l'utilisation de plusieurs instances d'un module de données, de sorte que la liaison automatique des commandes conscientes de données ne finit pas toujours à l'aide de la première instance. I> p>
Ajouter P> Ajouter P> Ajouter P >
p> après l'appel Créer et que vous devriez être fine p> p>
Le nom doit être unique ou rien. myfrm.nom: = '' code> est meilleur si vous ne vous souciez pas du nom, car vous n'avez pas besoin de trouver un nouveau nom et que le VCL permet de ne pas vérifier le nom de l'unicité.
Non. Delphi attribue automatiquement un nom unique aux formulaires créés de manière dynamique.
@Cosmin, oh Darn, c'est ce que je voulais dire, mais les fils dans mon cerveau ont été mélangés. Le nom de réglage sur une chaîne vide est ce que je fais toujours pour les datamodules instanciées plusieurs fois. Réponse modifiée.
Donner MainForm em> comme le propriétaire de tfrm1.create em> inclura le formulaire nouvellement créé dans la liste des composants de Mainform. Un composant garantit que cette liste ne contient pas deux composants avec le même nom non vide (sinon FindComponce ne fonctionnera pas). Ce mécanisme fonctionne également lorsqu'un composant change son nom. Tant que vous ne spécifiez pas le nom de tfrm1.create, il est très probable qu'il soit défini par la méthode LoadFromFile, ce qui signifie que vous n'avez pas beaucoup influencer sur le nom sauf si vous modifiez le contenu du fichier. p> Un contournement valide est de créer le formulaire avec NIL comme propriétaire, chargez le formulaire dans le fichier, modifiez le nom en une valeur unique ou à une chaîne vide. et enfin appeler mainform.insercomponent. p>
Salut uwe. J'ai pris votre conseil et j'ai fait une recherche de «nom» dans toute l'unité FRM1 (j'ai également inspecté manuellement LoadFromfile - juste pour être sûr). Personne ne définit la propriété "nom".
Je l'ai fait mais à la fin de la procédure myProcedure1. C'est la même chose que votre idée depuis à ce moment-là, la MRFRM sort de la portée et personne d'autre n'y a accès.
Même si myFRM (la variable) dépasse, la forme elle-même existe non seulement dans le tas, mais également en tant que membre d'une liste globale de formes appartenant à l'écran Objets globaux. Ainsi, l'exigence pour le nom unique (ou sinon aucun nom du tout). Je n'étais pas au courant de la fonctionnalité unique-nommage automatique déjà à Delphi, alors je suppose que le problème se produit ailleurs au plus profond de la VCL / RTL. Supposons que vous avez essayé le nom: = '' Pour voir si cela le résout?
En ce qui concerne mon exploration le long de cette ligne, oui le problème de « existe déjà » vient d'avoir intances de l'éditeur avec la même valeur pour la propriété Nom. Comme un autre travail autour de ne pas créer visuellement l'éditeur (s). Créer un nouveau composant à base de TForm / TFrame / TPanel pour l'éditeur (s) que vous souhaitez que l'utilisateur pour pouvoir créer plusieurs instances de. Vous devrez coder manuellement la création et la suppression de toutes les sous-contrôles, définissant leurs propriétés dans votre code et attribuer des valeurs - quelque chose de V_Btn = new TBitBtn (this), V_Btn-> Couleur = clTeal, à V_Btn-> onclick = Close_The_Window . Mais jamais attribuer une valeur à la propriété Nom de tout composant dans la nouvelle classe et ne définissez pas la propriété Nom de l'éditeur une fois que vous avez créé une instance de l'éditeur. Traiter la propriété Nom pour l'éditeur comme si elle n'existait pas. Après avoir créé la classe et l'ajouter à votre projet ce qui suit est valide:
if (typeid(New).name() == "TMyEditor *")
New_Editor->Parent = Tab_Sheet_Addresses;
else
if (typeid(New).name() == "TMyEditor_Generation_01 *")
New_Editor->Parent = Tab_Sheet_Billing;
else
if (typeid(New).name() == "TMyEditor_Generation_02 *")
New_Editor->Parent = Tab_Sheet_Other_Editor;
Aucun de cela n'a rien à voir avec la question posée, qui portait sur un problème créant plusieurs instances d'un formulaire à Runtime B>. La question n'a absolument rien faire avec l'éditeur de temps de conception, les éditeurs de propriétés, l'enregistrement de cours ou autre chose dans toute votre réponse.
Euh, quel est ce
chargéFOMFile code> méthode? Ce doit être l'un des vôtres, à moins que ce ne soit quelque chose ajouté dans Xe.@David, j'ai mentionné le
loadfromfile code> comme une cause dans les commentaires à deux réponses. Comme OP ne l'a pas mentionné, je suppose que ce n'est pas leloadfromfile code>.@Lieven dans le code qui est donné par l'OP, le seul endroit où il pourrait échouer est le
loadfromfile code>. Sans savoir ce que nous sommes réduits à deviner. Si @Altar veut nous faire savoir ce queloadfromfile code> est alors sûr que tout va tomber clairement.@David, c'était mon hypothèse. Si OP dit que ce n'est pas le cas, ce n'est pas ou il se trompe. Comme je l'ai ajouté dans un autre commentaire, OP devrait remplacer la méthode de SetName et placer un point d'arrêt.
@Lieven je veux dire, comment ne pourrait-il pas être dans "loadfromfile"?
@Altar: peut i> vous reproduisez l'erreur? Ou essayez-vous simplement de comprendre comment la reproduit?
@Jorn - Non, je ne peux pas reproduire l'erreur.
@Lieven - J'ai vérifié la valeur de 'Myfrm.name' à la fin de la procédure MyProcedure1; après chargefromfile. Le nom est unique.
@Altar, ce n'est pas ce que j'ai suggéré. Remplacer la méthode Code> SetName Code> Dans votre classe
TFRM1 CODE> et ajouter un point d'arrêt Il y a imo le moyen le plus rapide et le meilleur de détecter quels noms sont attribués.@Lieven: Quel est le point quand il n'y a pas d'erreur pour suivre? @Altar ne constatera que tout fonctionne comme prévu ... ne devrait-il pas être reproduit en premier?
@Jorn - Je ne peux pas le reproduire. Mais j'ai une capture d'écran pour un utilisateur. L'erreur existe!
@Altar, es-tu par hasard en utilisant plusieurs threads?
@Altar: OK. Ensuite, nous ne pouvons pas dire que l'utilisateur est allongé soit :-p la chose étrange, alors, est que l'erreur correspond à
'tfrm1' code> comme nom du composant. Comment cela peut-il être, lorsque la classe est nommée'tfrm1' code>? L'extrait de code est-il exactement le même que votre code de production? C'est à dire. La fonction est une fonction et non une méthode? Les noms sont-ils les mêmes? Est-ce untfRM1 code> -Form autocréé dans le fichier .dPR? Quelle est la «propriété» de la propriété danstfrm1 code> S. S Objet Inspecteur?@Jorn - (+1) Bingo! Que la meilleure question posée. Je suis totalement d'accord avec ça. C'est pourquoi j'ai utilisé le mot "étrange" dans mon post. Les noms générés automatiquement sont comme MyFrM_1, MYFRM_2, etc. Pourquoi l'erreur dit 'TFRM1' ????????????? Voir aussi Editer 5.
@Altar, il vient de pénétrer ma conscience que j'ai vu cette même erreur, mais je ne pense que sur le terrain et pas en interne. Je ne suis pas sûr à 100% de la cause et devrait creuser un peu. Pourriez-vous poster le contenu de tfrm1.create, TFRM1.Destroy et n'importe quel code dans Oncreate / Ondestroy.
@Altar: Vérifiez ce lien gnostice.com/... et trouver s'il y a une erreur comme celle de votre code
Bonjour Bharat - Je viens de vérifier mon code. Ce n'est pas que. En tout cas Bel article. J'espère que mon erreur n'est pas aussi stupide que celle :)
@Avid Heffernan - En Oncreate / Détruire Il n'y a qu'une "banque d'accès ini" très basique: myInifile: = tinifile.create (Appinifile) BLABLA
@altar protège qu'avec un essai à l'exception du bloc et tout ce qui peut lancer une construction ou une destruction. Avaler des exceptions. Ensuite, essayez sur la machine cliente.
J'ai commencé à avoir cette même erreur à partir d'un certain nombre de mes clients. Je ne peux pas non plus la reproduire localement. Il est également intermittent pour les utilisateurs. J'ai une pile d'appels madexcepte qui montre être à l'intérieur de tcustomform.create -> ... -> TControl.setname -> Tcomponent.setname -> TComponent.validaterename. Vraiment rien de plus à ajouter que ce n'est pas déjà dans la question. Il est agréable de savoir que je ne suis pas le seul à combattre cela. J'utilise Delphi 2007.
Je me rends compte que c'est un ancien poste, mais pour ceux qui arrivent ici via le moteur de recherche. Si vous utilisez des cadres et que vous obtenez cette erreur, dites-vous lorsque vous migrez d'une version de Delphi ou d'une tierce partie à une autre. Ouvrez d'abord les cadres et enregistrez-le - avant de sauver le (s) conteneur (s) du cadre. Exemple spécifique: avec le nouveau ReportBuilder (V18), je reçois une erreur "composant nommé Raprograminfo existe déjà". C'était un code DFM autogénéré. Ouverture du cadre contenant le (s) composant (s) incriminé (s), épargnant, puis ouvrant la forme contenant et économiser à nouveau, résolvé le problème dans ce cas. J'espère que cela t'aides!