I'm using Delphi 7. When I try to create an object in FormCreate, it fails (actually it just hangs). When I try to do the same thing in FormShow, it works. Please note, I'm not talking about creating a visual component like a TEdit. It's a database abstraction object. Any ideas why this might happen? Are there any guidelines about this topic?
+2
A:
My first guess is that you're accessing a DataModule hasn't been created yet. If your project's source looks like the following:
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TDataModule1, DataModule1);
Application.Run;
end.
And your TForm1.FormCreate
looks like the following:
begin
DataModule1.AddUsersToStringList(Self.ComboBox1.Items);
end;
Then FormCreate
going to fail because it's is being run as part of the Application.CreateForm(TForm1, Form1);
line, and your Data Module hasn't been created yet.
There's 2 solutions:
- Defer your processing/initialization until after all the forms and data modules have been created.
- Create all the data modules before creating any of your forms. The Application's "Main Form" in Delphi is the first
TCustomForm
descendant created byApplication.CreateForm
, not the first object.
afrazier
2010-07-16 14:15:18
But that should cause an access violation... not hanging.
Craig Young
2010-07-17 20:37:44
@afrazier: In a simple scenario, your answer is correct.. but not in this case. I assure you, the datamodule, queries, and associated clientdataset are already created when this form's FormCreate is called. It's not the applications main form. The datamodule has lond been created.
Sam
2010-07-18 22:55:03
@Craig Young: you're absolutely right. That's the thing, it just hangs (like an infinite loop!).
Sam
2010-07-18 22:57:02
+2
A:
1) The reason is because on FormCreate, the handle to Form is not created yet.
If your database object needs a form handle, do this:
Self.HandleNeeded; // on FormCreate time.
2) The other reason is maybe your database component needs to be connected and it's only connected on DFM?
buttercup
2010-07-16 14:21:51
`TWinControl.GetHandle` (which is what gets called when you attempt to retrieve a form's handle) calls `HandleNeeded` internally before returning the handle.Also, if a connection component has `Connected = True` stored in the DFM, then the compiled application should connect as soon as the property is streamed in when instantiating the component. The only time this wouldn't be the case is if you have an IDE expert that forces the compiled state to be `Connected = False` in the built executable.
afrazier
2010-07-16 15:41:20
the person who asked this question did not state which database object he used. I remember using BTrieve for Windows which is non-TDataSet-based and had this problem.
buttercup
2010-07-16 20:49:51
@buttercup: Not #2, but your #1 sounds plausible. That's the kind of answer I was looking for. The object is too big and complex to dig into any further, and I know it works fine if I call it from FormShow. Thanks, I'm accepting this answer and upvoting all contributors.
Sam
2010-07-18 23:11:17