TheBreeze
asked on
Form Show (for 150 points)
Hi experts,
I'm depositing 25 points for this question but if it gets answered satisfactorily I'll give out 150 points.
My code has been acting rather weird (at least as it appears to me) lately. I set up three breakpoints in the code, one in the main form's call to create of another form (Breakpoint A), another in call to show the form(Breakpoint B), and another in the form's OnShow handler
(Breakpoint C). See the code below. My problem is Breakpoint C is reached before breakpoint B. As you can see in the code, the OnSHow handler of MyFrm calls a procedure that accesses MyList, a property in MyFrm. At Breakpoint C, MyFrm is still nil therefore an error is generated when the AddItem procedue is called.
procedure TMainFrm.ChartsExecute(Sen der: TObject);
begin
if not Assigned(MyFrm) then
MyFrm:=TMyFrm.Create(appli cation);{b reakpoint here A}
MyFrm.Show;{breakpoint B}
end;
procedure TMyFrm.FormShow(Sender: TObject);
begin
AddItem; {breakpoint C, AddItem is a function defined in another unit}
end;
//another unit :
procedure AddItem
begin
Memo.Lines.Add(MyFrm.MyLis t.Items[1] );
end;
Below is the definition of TMyFrm :
TMyFrm = class(TMy2Class)
MyList1: TMyList;{a component I derived from TList}
private
public
end;
TMy2Class is a class derived from other classes derived from TForm,
something like :
TMy2Class= class(TMy1Class)
TMy1Class= class(TForm)
The contents of the CallStack upon reaching Breakpoint C is as follows:
TMyFrm.FormShow
TCustomForm.DoShow
TCustomForm.CMShowingChang ed
TCustomForm.WndProc
TCustomForm.WndProc
TCustomForm.AfterConstruct ion
TMainFrm.ChartsExecute
This doesn't happen in the other forms. One of the hyphothesis that I have is that MyFrm was not derived directly from TForm.
Cheers!
-Tony
I'm depositing 25 points for this question but if it gets answered satisfactorily I'll give out 150 points.
My code has been acting rather weird (at least as it appears to me) lately. I set up three breakpoints in the code, one in the main form's call to create of another form (Breakpoint A), another in call to show the form(Breakpoint B), and another in the form's OnShow handler
(Breakpoint C). See the code below. My problem is Breakpoint C is reached before breakpoint B. As you can see in the code, the OnSHow handler of MyFrm calls a procedure that accesses MyList, a property in MyFrm. At Breakpoint C, MyFrm is still nil therefore an error is generated when the AddItem procedue is called.
procedure TMainFrm.ChartsExecute(Sen
begin
if not Assigned(MyFrm) then
MyFrm:=TMyFrm.Create(appli
MyFrm.Show;{breakpoint B}
end;
procedure TMyFrm.FormShow(Sender: TObject);
begin
AddItem; {breakpoint C, AddItem is a function defined in another unit}
end;
//another unit :
procedure AddItem
begin
Memo.Lines.Add(MyFrm.MyLis
end;
Below is the definition of TMyFrm :
TMyFrm = class(TMy2Class)
MyList1: TMyList;{a component I derived from TList}
private
public
end;
TMy2Class is a class derived from other classes derived from TForm,
something like :
TMy2Class= class(TMy1Class)
TMy1Class= class(TForm)
The contents of the CallStack upon reaching Breakpoint C is as follows:
TMyFrm.FormShow
TCustomForm.DoShow
TCustomForm.CMShowingChang
TCustomForm.WndProc
TCustomForm.WndProc
TCustomForm.AfterConstruct
TMainFrm.ChartsExecute
This doesn't happen in the other forms. One of the hyphothesis that I have is that MyFrm was not derived directly from TForm.
Cheers!
-Tony
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
try to use active event instead of show event (for break c)
I guess TMyFrm.Visible is true in the object inspector. Set it to false. This should solve the problem.
Regards, Madshi.
Regards, Madshi.
Hello,
Is the visible property of TMyFrm set to true. If it were it would cause the problems that you are experiencing. By default it should be false, but you never know...
Jo
Oops. Ignore my comments Madshi got there first.
ASKER
TMyFrm.Visible is set to false
Hello
try as I told you before, to change the code from the event show to active, the event active execute when the form draw in the screen
try as I told you before, to change the code from the event show to active, the event active execute when the form draw in the screen
Hmmmm... Then maybe the TMyFrm.OnCreate handler set TMyFrm.Visible to true? Or calls Show? Or something like that? Someone has to do that somewhere, otherwise your breakpoint would not be "confused".
Regards, Madshi.
Regards, Madshi.
P.S: Why not stepping line by line through the code? Then you should see from where the code jump to the TMyFrm.FormShow handler.
ASKER
TMyFrm.Visible is set to false
ASKER
mnasman,
I'm not quite sure what you mean. Do you mean I should use MyFrm.Active:=true instead of MyFrm.Show?
madshi,
I traced the program and right after the form create
procedure the code jumped to the following :
procedure TCustomForm.DoCreate;
begin
if Assigned(FOnCreate) then
try
FOnCreate(Self);
except
Application.HandleExceptio n(Self);
end;
if fsVisible in FFormState then Visible := True;
end;
For additional info, as I have already written above:
The contents of the CallStack upon reaching Breakpoint C are as follow:
TMyFrm.FormShow
TCustomForm.DoShow
TCustomForm.CMShowingChang ed
TCustomForm.WndProc
TCustomForm.WndProc
TCustomForm.AfterConstruct ion
TMainFrm.ChartsExecute
Experts, thank you for your time. Got to go home now. I'll be checking in again tomorrow.
I'm not quite sure what you mean. Do you mean I should use MyFrm.Active:=true instead of MyFrm.Show?
madshi,
I traced the program and right after the form create
procedure the code jumped to the following :
procedure TCustomForm.DoCreate;
begin
if Assigned(FOnCreate) then
try
FOnCreate(Self);
except
Application.HandleExceptio
end;
if fsVisible in FFormState then Visible := True;
end;
For additional info, as I have already written above:
The contents of the CallStack upon reaching Breakpoint C are as follow:
TMyFrm.FormShow
TCustomForm.DoShow
TCustomForm.CMShowingChang
TCustomForm.WndProc
TCustomForm.WndProc
TCustomForm.AfterConstruct
TMainFrm.ChartsExecute
Experts, thank you for your time. Got to go home now. I'll be checking in again tomorrow.
no, i don't mean to change the event from onshow to onactivate
procedure TMyFrm.FormShow(Sender: TObject);
begin
AddItem; {breakpoint C, AddItem is a function defined in another unit}
end;
procedure TMyFrm.FormActivate(Sender : TObject);
begin
AddItem; {breakpoint C, AddItem is a function defined in another unit}
end;
also I think you should remove the MyFrm from the autocreate opetion from projects menu, cuz u create it in run time and you don't need delphi to create it for you
to remove it from the Auto-create
goto to project menu > options
remove MyFrm from auto-create forms to avaible forms
procedure TMyFrm.FormShow(Sender: TObject);
begin
AddItem; {breakpoint C, AddItem is a function defined in another unit}
end;
procedure TMyFrm.FormActivate(Sender
begin
AddItem; {breakpoint C, AddItem is a function defined in another unit}
end;
also I think you should remove the MyFrm from the autocreate opetion from projects menu, cuz u create it in run time and you don't need delphi to create it for you
to remove it from the Auto-create
goto to project menu > options
remove MyFrm from auto-create forms to avaible forms
Okay, there we have it! It seems that "FFormState" contains the "fsVisible" flag. The big question is: How does the flag come there? There's only one possibility: Look at the code from "TCustomForm.SetVisible" in the "forms" unit. That's the only location where the "fsVisible" flag is set. That means, someone is calling SetVisible of your TMyFrm (or setting "Visible := true"). My suggestion: Set a breakpoint to "TCustomForm.SetVisible". If you get there, look at the callstack and go through it, then you should find the guilty one, who makes your TMyFrm visible.
Regards, Madshi.
Regards, Madshi.
It appears to me that your problem is two-fold.
First, as Madshi pointed out, someone's messing with
your form behind your back;
but secondly and more importantly, when that someone
does show your form, there shouldn't be an access violation
if MyList has been created.
Make sure MyList is created and initialized BEFORE the FormShow event. You could create the list in MyFrm.FormCreate, this way even if someone else does create
and show your form, the list will be ready to receive new
items anyway.
HTH,
rondi
First, as Madshi pointed out, someone's messing with
your form behind your back;
but secondly and more importantly, when that someone
does show your form, there shouldn't be an access violation
if MyList has been created.
Make sure MyList is created and initialized BEFORE the FormShow event. You could create the list in MyFrm.FormCreate, this way even if someone else does create
and show your form, the list will be ready to receive new
items anyway.
HTH,
rondi
ASKER
mnasman,
-I don't think FormActivate would do
-MyFrm is not autocreate
Madshi,
I took your advice and the editor took me deep into the Forms unit without seeing any light.
Anyway, I think the "error" is brought about by the fact that TMyFrm was derived from other classes.
rondi,
MyList is an installed user component which is added to MyFrm. I don't think it should still be created
Actually the solution proposed by Jaymol works. I removed the OnShow event handler and transfered the code to another procedure, and called that procedure after creating the form.
procedure TMainFrm.ChartsExecute(Sen der: TObject);
begin
if not assigned(ChartFrm) then
ChartFrm:=TChartFrm.Create (applicati on);
ChartFrm.MyCustomShow;
end;
I didn't want to accept it as a solution in the beginning because it is just a workaround - it doesn't really explain why breakpoint B is reached before breakpoint C. The solution proposed by Madshi may work, but it would probably take more time before I figure out how to figure it out.
Anyway, I guess since it's the solution of Jaymol that I will implement, he ought to receive the credit. But I'll only give out 100 points since the solution is just a workaround.
Thank you all for your help and your time.
-I don't think FormActivate would do
-MyFrm is not autocreate
Madshi,
I took your advice and the editor took me deep into the Forms unit without seeing any light.
Anyway, I think the "error" is brought about by the fact that TMyFrm was derived from other classes.
rondi,
MyList is an installed user component which is added to MyFrm. I don't think it should still be created
Actually the solution proposed by Jaymol works. I removed the OnShow event handler and transfered the code to another procedure, and called that procedure after creating the form.
procedure TMainFrm.ChartsExecute(Sen
begin
if not assigned(ChartFrm) then
ChartFrm:=TChartFrm.Create
ChartFrm.MyCustomShow;
end;
I didn't want to accept it as a solution in the beginning because it is just a workaround - it doesn't really explain why breakpoint B is reached before breakpoint C. The solution proposed by Madshi may work, but it would probably take more time before I figure out how to figure it out.
Anyway, I guess since it's the solution of Jaymol that I will implement, he ought to receive the credit. But I'll only give out 100 points since the solution is just a workaround.
Thank you all for your help and your time.
Thanks.