sepknow
asked on
Delphi 6 form question
Further to my question in
https://www.experts-exchange.com/questions/26914474/Delphi-6-form-question.html
1) There is no code in OnClose or OnCloseQuery or finalization.
2) I have added log statement in every event handler and functions/procedures.
3) The OnShow was trigger once only.
4) There was no exception. Nothing to catch in my exception handler.
5) I do have other event handlers shown below. But I think they do not
pose any problem.
What else could have caused my form not to close?
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if (Key = VK_F4) and (ssAlt in Shift) then
Key:=0;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (gStatus = Open) then begin
//If the form is opened/visible
//Bring it to the front
//position it to the center
self.BringToFront;
self.Left:=(Screen.Desktop Width - self.Width) div 2;
self.Top:=(Screen.DesktopH eight - self.Height) div 2;
//log
end;
end;
https://www.experts-exchange.com/questions/26914474/Delphi-6-form-question.html
1) There is no code in OnClose or OnCloseQuery or finalization.
2) I have added log statement in every event handler and functions/procedures.
3) The OnShow was trigger once only.
4) There was no exception. Nothing to catch in my exception handler.
5) I do have other event handlers shown below. But I think they do not
pose any problem.
What else could have caused my form not to close?
procedure TForm1.FormKeyDown(Sender:
begin
if (Key = VK_F4) and (ssAlt in Shift) then
Key:=0;
end;
procedure TForm1.Timer1Timer(Sender:
begin
if (gStatus = Open) then begin
//If the form is opened/visible
//Bring it to the front
//position it to the center
self.BringToFront;
self.Left:=(Screen.Desktop
self.Top:=(Screen.DesktopH
//log
end;
end;
ASKER
Thanks.
There is no inheritance.
No subclassing either.
I do handler global exception but no error message was reported.
No handlers in Form1 was fired from other forms.
But I do set the variables declared in Form1 from the main form.
for example, gStatus declared in Form1:
type
TForm1 = class(TForm)
rg1: TRadioGroup;
private
{ Private declarations }
public
{ Public declarations }
gStatus:EStatusType;
end;
There is no inheritance.
No subclassing either.
I do handler global exception but no error message was reported.
No handlers in Form1 was fired from other forms.
But I do set the variables declared in Form1 from the main form.
for example, gStatus declared in Form1:
type
TForm1 = class(TForm)
rg1: TRadioGroup;
private
{ Private declarations }
public
{ Public declarations }
gStatus:EStatusType;
end;
so there are references between forms
and modifications of variables from other forms
how do you do the changes ?
it may be best to use property getters/setters for public variables
type
TForm1 = class(TForm)
private
fgStatus: EStatusType;
function GetGStatus: EStatusType;
procedure SetGStatus(const Value: EStatusType);
public
property gStatus: EStatusType read GetGStatus write SetGStatus;
end;
function TForm1.GetGStatus: EStatusType;
begin
Result := fgStatus;
end;
procedure TForm1.SetGStatus(const Value: EStatusType);
begin
if csDestroying in ComponentState then
raise Exception.Create('TForm1 instance is being destroying. Check call stack with Ctrl-F3');
fgStatus := Value;
end;
and modifications of variables from other forms
how do you do the changes ?
it may be best to use property getters/setters for public variables
type
TForm1 = class(TForm)
private
fgStatus: EStatusType;
function GetGStatus: EStatusType;
procedure SetGStatus(const Value: EStatusType);
public
property gStatus: EStatusType read GetGStatus write SetGStatus;
end;
function TForm1.GetGStatus: EStatusType;
begin
Result := fgStatus;
end;
procedure TForm1.SetGStatus(const Value: EStatusType);
begin
if csDestroying in ComponentState then
raise Exception.Create('TForm1 instance is being destroying. Check call stack with Ctrl-F3');
fgStatus := Value;
end;
ASKER
I need at least one day to test it.
Thanks.
Thanks.
don't give this to the users ...
you need to run this in delphi itself
after you hit close, you may get an exception
hit Ctrl-F3 to see where the call came from
you need to run this in delphi itself
after you hit close, you may get an exception
hit Ctrl-F3 to see where the call came from
ASKER
Will it helps if I use Tbutton instead of TBitBtn?
no difference, they are both descendants of TWinControl
there would be a difference if using a TSpeedBtn instead
TSpeedBtn doesn't get focus when clicked, other button types do
there would be a difference if using a TSpeedBtn instead
TSpeedBtn doesn't get focus when clicked, other button types do
in unit1, are you "using mainunit" ?
if so, you have circular unit reference ...
not really a culprit, but a secondary problem, which may complicate the matters a little
if so, you have circular unit reference ...
not really a culprit, but a secondary problem, which may complicate the matters a little
ASKER
yes, but it is after the implementation.
ASKER
And, will it helps, if I hide the form instead of closing the form?
>>yes, but it is after the implementation.
????
hiding will not give an error ... the error will happen when closing the application completely
????
hiding will not give an error ... the error will happen when closing the application completely
aha>>yes, but it is after the implementation.
lol, i got it ... you indeed have circular unit reference
it would be best to avoid that practice
if you need help in solving that problem too
> remove the mainunit from the uses section from unit1
> and post the code where the problem occurs
> i'll show the way to do it without circular unit reference
> this may also solve your closing problem
lol, i got it ... you indeed have circular unit reference
it would be best to avoid that practice
if you need help in solving that problem too
> remove the mainunit from the uses section from unit1
> and post the code where the problem occurs
> i'll show the way to do it without circular unit reference
> this may also solve your closing problem
ASKER
Thanks.
The line in the save button click event:
procedure TForm1.bbSaveClick(Sender: TObject);
begin
...
MainForm.FillGrid('HighCou nt');
...
end;
The line in the save button click event:
procedure TForm1.bbSaveClick(Sender:
begin
...
MainForm.FillGrid('HighCou
...
end;
what does that save do ?
do you reference Form1 information from MainForm.Fillgrid ?
post the code with the references to Form1 from FillGrid/MainUnit
this is probably the cause of your problem ... i'm guessing probably 99% ... :)
do you reference Form1 information from MainForm.Fillgrid ?
post the code with the references to Form1 from FillGrid/MainUnit
this is probably the cause of your problem ... i'm guessing probably 99% ... :)
ASKER
This function does quite a few things.
1) Read some data from the sql database
2) Fill the data into the TStringGrid
3) and finally issue a "Close" statement in the finally block.
no references to the Form1.
1) Read some data from the sql database
2) Fill the data into the TStringGrid
3) and finally issue a "Close" statement in the finally block.
no references to the Form1.
what TStringGrid ?
where is that located on Main Form ?
what information are you putting in the grid and where does it come from ?
and why do you put that code in TForm1 ?
shouldn't it be in Main Form ?
after all, it's probably changing something in main form ...
where is that located on Main Form ?
what information are you putting in the grid and where does it come from ?
and why do you put that code in TForm1 ?
shouldn't it be in Main Form ?
after all, it's probably changing something in main form ...
ASKER
Yes, the TStringGrid is located in the Main Form.
It reads the data from SQL server and populate into the grid.
TForm1 merely called the function in mainform to populate the grid.
to tell the user that data entered in TForm1 is saved into the database.
It reads the data from SQL server and populate into the grid.
TForm1 merely called the function in mainform to populate the grid.
to tell the user that data entered in TForm1 is saved into the database.
that's not the good way to program
it's quick, yes, but it makes mainform dependant on form1 and vice versa
not good if you design multiple apps with common code
I assume you show Form1 ShowModal ?
and want to close it with save button ?
unit1 sample (most simple form)
main unit call
in unit1 there is no "uses MainUnit"
it's quick, yes, but it makes mainform dependant on form1 and vice versa
not good if you design multiple apps with common code
I assume you show Form1 ShowModal ?
and want to close it with save button ?
unit1 sample (most simple form)
unit Unit1;
type
TForm1 = class(TForm)
...
end;
function ShowSubForm1Modal(aOwner: TComponent): boolean;
implementation
function ShowSubForm1Modal(aOwner: TComponent): boolean;
var F: TForm;
begin
Result := False;
F := TForm1.Create(aOwner);
try
if F.ShowModal = mrOk then
Result := True;
finally
F.Free;
end;
end;
main unit call
uses Unit1;
procedure TMainForm.Button1Click(Sender: TObject);
begin
if ShowSubForm1Modal(Self) then
FillGrid('HighCount');
end;
in unit1 there is no "uses MainUnit"
ASKER
Thanks.
Its Form1.Show()
=(
That is why I put all the tasks in Form1.
May I know what is the best practice, in this case?
Its Form1.Show()
=(
That is why I put all the tasks in Form1.
May I know what is the best practice, in this case?
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
Thank you for your help.
do you inherit this form from another one you created ?
> a handler could be set in the parent
type
TForm1 = class(TOtherForm)
or have you done any subclassing of TForm in one of your own units like this:
type
TForm = class(forms.TForm)
do you have exception handling for the application ?
application.OnException := ...
are any handlers fired from other forms, eg:
procedure TForm2.OnBtn1Click(Sender:
begin
Form1.HandleSomething(Self
end;
>> Form1 variable would be the problem here ... it's destroying ...