2010-07-16 9 views
1

J'utilise Delphi 7. Lorsque j'essaie de créer un objet dans FormCreate, il échoue (en fait, il se bloque). Quand j'essaye de faire la même chose dans FormShow, ça marche. S'il vous plaît noter, je ne parle pas de créer un composant visuel comme un TEdit. C'est un objet d'abstraction de base de données. Des idées pour lesquelles cela pourrait arriver? Y a-t-il des directives sur ce sujet?Pourquoi quelque chose échouerait dans FormCreate, mais fonctionnerait bien dans FormShow?

+7

Plus de détails aiderait. Quel genre d'objet est-ce? Est-ce quelque chose de standard que nous connaîtrions? Qu'est-ce qu'il essaie de faire dans son constructeur? À quel moment est-ce que ça pète? Qu'est-ce que le débogueur vous a dit à propos du problème jusqu'à présent? –

+1

Notez que les instructions de débogage, telles que la sortie sur une console telle que GExperts Debuger ou SmartInspect, peuvent vous aider à identifier la ligne sur laquelle elle est suspendue. Alors la réponse est généralement évidente. –

+0

@Mason Wheeler: C'est un objet d'abstraction de données personnalisé que nous avons construit en interne. Non, je ne m'attends pas à ce que quelqu'un le connaisse. Il interroge la base de données et remplit ses propriétés avec des valeurs provenant des résultats de la requête. Il se bloque en essayant d'ouvrir le CDS depuis l'intérieur du constructeur. Peu importe le débogueur, je veux savoir pourquoi cela fonctionne depuis FormShow mais pas avec FormCreate (vous pouvez supposer que le module de données sous-jacent, la requête et le clientdataset associé existent déjà - sinon j'obtiendrais une violation d'accès). – Sam

Répondre

2

1) La raison en est que sur FormCreate, le descripteur à Form n'est pas encore créé.

Si votre objet de base de données a besoin d'une poignée de forme, faites ceci:

Self.HandleNeeded; // sur FormCreate time.

2) L'autre raison est peut-être que votre composant de base de données doit être connecté et qu'il est seulement connecté sur DFM?

+2

'TWinControl.GetHandle' (qui est ce qui est appelé lorsque vous essayez de récupérer le handle d'un formulaire) appelle 'HandleNeeded' en interne avant de retourner le handle. En outre, si un composant de connexion a 'Connected = True' stocké dans le DFM, l'application compilée doit se connecter dès que la propriété est diffusée lors de l'instanciation du composant. La seule fois où cela ne serait pas le cas est si vous avez un expert IDE qui force l'état compilé à être Connected = False dans l'exécutable construit. – afrazier

+1

la personne qui a posé cette question n'a pas précisé quel objet de base de données il a utilisé. Je me souviens d'utiliser BTrieve pour Windows qui n'est pas basé sur TDataSet et qui a ce problème. – buttercup

+0

Pas # 2, mais votre # 1 semble plausible. C'est le genre de réponse que je cherchais. L'objet est trop gros et trop complexe pour que l'on puisse en trouver d'autres, et je sais que cela fonctionne très bien si je l'appelle depuis FormShow. Merci, j'accepte cette réponse et upvoting tous les contributeurs. – Sam

2

Ma première supposition est que vous accédez à un DataModule n'a pas encore été créé. Si votre source de projet se présente comme suit:

begin 
    Application.Initialize; 
    Application.CreateForm(TForm1, Form1); 
    Application.CreateForm(TDataModule1, DataModule1); 
    Application.Run; 
end. 

Et votre TForm1.FormCreate se présente comme suit:

begin 
    DataModule1.AddUsersToStringList(Self.ComboBox1.Items); 
end; 

Alors FormCreate va échouer parce qu'il est est en cours d'exécution dans le cadre de la ligne Application.CreateForm(TForm1, Form1);, et votre Le module de données n'a pas encore été créé.

Il y a 2 solutions:

  1. Différer votre traitement/initialisation jusqu'à ce que tous les formulaires et les modules de données ont été créés.
  2. Créez tous les modules de données avant de créer l'un de vos formulaires. Le "formulaire principal" de l'application dans Delphi est le premier TCustomForm descendant créé par Application.CreateForm, pas le premier objet.
+1

Mais cela devrait causer une violation d'accès ... pas suspendu. –

+0

Dans un scénario simple, votre réponse est correcte .. mais pas dans ce cas. Je vous assure que le datamodule, les requêtes et le clientdataset associé sont déjà créés lors de l'appel de FormCreate de ce formulaire. Ce n'est pas le formulaire principal des applications. Le datamodule a été créé. – Sam

+0

@Craig Young: vous avez absolument raison. C'est la chose, ça pend (comme une boucle infinie!). – Sam