4

I'm working with someone else's code, and I'm adding a new form

So, I've created the form and I can open it, use the buttons and list, etc, but I'm having a problem doing things on formcreate.

I make the form by doing this:

procedure TModelForm.RepeatOpen(Sender: TObject);
var
 DefForm : TForm5;
begin
 DefForm := TForm5.Create(Self);

 Self.Visible := False;
 try
  DefForm.ShowModal;
 finally
  Self.Visible := True;
  DefForm.Release;
 end;
end;

in my TForm5, I have a procedure

procedure TForm5.FormCreate(Sender: TObject);
begin
 inherited;
 RunList := CModelList.Create;
 RunList.ReadData;
 RunList.FillList(ListBox1.Items);
end;

but it doesn't do anything

I also have

procedure TForm5.PopulateListClick(Sender: TObject);
begin
 RunList := CModelList.Create;
 RunList.ReadData;
 RunList.FillList(ListBox1.Items);
end;

which is assigned to a button, and this actually works and populates my ListBox

I've been looking it up online and it seems like there is no OnCreate function, there is a way to override it but it seems like there should be a way to just define what happens when the frame is first created

also, the reason I'm using FormCreate is because that's what the code I'm working with is doing, and it seems to be working

Thanks!

2
  • Why do you call "inherited" in the FormCreate? Is TForm5 = class (TForm)? Then this is not correct! "Inherited" must be called, if you make your own constructor, but not in Events! Have you assigned your event to the Forms "OnCreate"? Commented May 12, 2011 at 17:31
  • 2
    @andreas nothing wrong with inherited in events and indeed the IDE puts it in for you. Commented May 12, 2011 at 19:33

3 Answers 3

6

You've probably forgotten to assign FormCreate to OnCreate. Personally I'd do it by overriding the constructor and so keeping the .dfm form out of the way.

As an aside I would like to comment on the code you wrote:

DefForm := TForm5.Create(Self);
Self.Visible := False;
try
  DefForm.ShowModal;
finally
  Self.Visible := True;
  DefForm.Release;
end;

You don't need to assign an owner to DefForm since you are taking on the task of cleaning up, although it generally does no harm to assign an owner. What's more the try/finally is try to do two jobs but it can only really do one. The call to Release is not needed, you can just call Free.

I'd write it like this:

DefForm := TForm5.Create(nil);
try
  Self.Visible := False;
  try
    DefForm.ShowModal;
  finally
    Self.Visible := True;
  end;
finally
  DefForm.Free;
end;
Sign up to request clarification or add additional context in comments.

8 Comments

@David - from time to time happens to me that even if I let the IDE create the event handler header for me, the *.dfm lose the connection to that handler later on. It's a bug which I can't reproduce and which occurs rarely. I've tried to apply IDE fix packs but it doesn't help. And because I'm lazy to write the headers and connect them to the events by myself, the easist way when this occurs is to reconnect them in Object Inspector.
@David - and why wouldn't try/finally do more than one thing in finally block ?
You also don't need to specifically refer to Self. Just Visible := False; ... Visible := true; would be enough.
@david self here makes it explicit which form is being made invisible.
@daemon in the original code the try only protects the assignment to visible. It doesn't properly protect the lifetime of DefForm. It is possible for an exception to be raised in self.visible := false and then the form will be leaked. Usually try can only protect the line immediately previous.
|
4

Do you mean, that your eventhandler is not executed? If so, did you maybe just forgot to assign the procedure to the Form's OnCreate property?

3 Comments

@KingKong - check the OnCreate event of your TForm5 in Object Inspector if is really assigned. If not, select it using combo or typing FormCreate in the OnCreate event row.
Oh, that's exactly what I was asking, I thought there should be a way to do this and I found it under Miscellaneous in the Object Inspector. Thanks
Or simply double click on any "empty" space on a form - not always possible if you have panels or other controls with alClient alignment. If you have "Display Grid" on in the form designer empty space will show the grid.
1

I've been looking it up online and it seems like there is no OnCreate function, there is a way to override it but it seems like there should be a way to just define what happens when the frame is first created

OK, I'm a bit confused here. Are you talking about a form or a frame? Forms have an OnCreate handler, but frames do not. If you want to make something happen when a frame is created, override the constructor.

constructor TMyFrame.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 RunList := CModelList.Create;
 RunList.ReadData;
 RunList.FillList(ListBox1.Items);
end;

Similarly, frames have no OnDestroy, so make sure to override the destructor if there's anything you need to clean up.

1 Comment

There is an onCreate event, but it's not published. But i agree, I would override the constructor - but i would move the loading etc. as i described above. Thumbs up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.