Board index » delphi » check report is closing

check report is closing

Hi,

I have severall report fired on desktop
the close buttom closes alle reports (checking for all QRStandardPreview
reports)
the close buttom also closes the form.

If I do not a delay for 1 second between the 2 actions I got an Access
viololation error
Is it possible to check if the reports are all closed, so I can close my
form
without making an delay

Thanks on any suggestion
Werner

 

Re:check report is closing


I'm using D3 and QR 2.0K

Re:check report is closing


Without seeing the code, the only thing I can suggest is putting
"Application.ProcessMessages" before the close command for the form.

It depends how you are calling the report and how you are freeing the
form.    If you are explicitly freeing it, you may find it better not
to do so but to put "Action := caFree" in its OnClose event so that
Delphi will free it when ready.

Regards,
Colin Acheson

On Wed, 15 Nov 2000 09:49:18 +0100, "Werner Selen"

Quote
<w...@village.uunet.be> wrote:
>Hi,

>I have severall report fired on desktop
>the close buttom closes alle reports (checking for all QRStandardPreview
>reports)
>the close buttom also closes the form.

>If I do not a delay for 1 second between the 2 actions I got an Access
>viololation error
>Is it possible to check if the reports are all closed, so I can close my
>form
>without making an delay

>Thanks on any suggestion
>Werner

Re:check report is closing


viewing and closing the reports usin D3 and QR2.0k :

procedure TQueryList.BitBtnVieuwClick(Sender: TObject);
begin
  RepMakeView:=TRepMakeView.Create(Application);
  RepMakeView.QRep.preview;
  { when 5 times or more making the same reports and then by closing them I
get
  { an access violation error, when free the reports
  { the same errors occurs with the examples of QSoft , custompreview
  // RepMakeView.free
end;
procedure TQueryList.CloseClick(Sender: TObject);
begin
    CloseReports;
    Application.ProcessMessages;
    { wait 1 second (using timer) and form will close ok}
    timer1.enabled:=True;
    { calling close without delay of 1 second , I have access violation
error}
    // close
end;

procedure TQueryList.Timer1Timer(Sender: TObject);
begin
  timer1.enabled:=False;
  close;
end;

procedure TQueryList.CloseReports;
var iTel: Integer;
begin
  try
    for iTel:= Screen.FormCount-1 downto 0 do
      if Screen.Forms[iTel].ClassName='TQRStandardPreview' then begin
        Screen.Forms[iTel].close;
      end;
  except
  end;
end;

{ closing the reports wil close all QRStandardPreview but not the
RepMakeView reports,
{ calling CaFree and RepMakeView:=nil in onClose will not  work  by closing
the reports (QRStandardPreview)
{ CaFree will only be called when closing the application or using
RepMakeView.Free, but this gives an error.
{ problem occurs when making 5 or more same reports without closing them
first and
{ 1.   using RepMakeView.Free
{ 2.   not using RepMakeView.Free but close the calling Form without waiting

{ problem solved by
{  not using RepMakeView.Free and close the calling Form and  waiting for 1
second or more
{  but this is not the way I like this, I want to know why this problem
occors

Hope this explain  my problem
Greetings
Werner

Quote
>Without seeing the code, the only thing I can suggest is putting
>"Application.ProcessMessages" before the close command for the form.

>It depends how you are calling the report and how you are freeing the
>form.    If you are explicitly freeing it, you may find it better not
>to do so but to put "Action := caFree" in its OnClose event so that
>Delphi will free it when ready.

>Regards,
>Colin Acheson

>>Hi,

>>I have severall report fired on desktop
>>the close buttom closes alle reports (checking for all QRStandardPreview
>>reports)
>>the close buttom also closes the form.

>>If I do not a delay for 1 second between the 2 actions I got an Access
>>viololation error
>>Is it possible to check if the reports are all closed, so I can close my
>>form
>>without making an delay

>>Thanks on any suggestion
>>Werner

Re:check report is closing


Werner,

I agree that you need to eliminate the cause of the problem so that
you can get rid of the timer.  It is not nice to rely on that.

I love your procedure for closing the previews.  I had something
similar to that but yours is better.   By counting downwards, you are
able to close all of them.

Just a couple of comments.  If you are creating and freeing forms
yourself, it is better to use Nil as the owner rather than Self or
Application.   If you use Application as the owner and then free the
form yourself, you may get an AV when the application also tries to
free the form but it no longer exists.   On the other hand, if you let
the application handle the freeing, then the free won't happen until
the app. closes, so all the forms you create will be taking up memory
and resources until then.  Using Nil as the owner also speeds up the
closing and freeing.   There was a very good article written about
this but I cannot remember where to find it.

I should mention that there is also a bug in Qrprntr.pas that causes
occasional AV's due to an uninitialised variable in the
TQRPrinter.Print procedure.  However you need the source code to fix
that.

This is how I would do it.  

(A) In the FormClose event of RepMakeView, place the line:
               Action := caFree;
This ensures that the free doesn't happen unless and until the form is
closed but it *does* always happen when the form is closed if the
owner is Nil.

(B) In the FormDestroy event of RepMakeView, place the following code.

  if assigned(RepMakeView) then RepMakeView := Nil;

(C) Move the call to CloseReports so that you do that before creating
a new report.   That way there will never be more than one report and
one preview in existence.  You then don't need to call CloseReports
when closing the calling form (although it wouldn't do any harm if you
did).   The problem of the preview not being freed only occurs when
there are more previews in existence than report forms.

procedure TQueryList.BitBtnVieuwClick(Sender: TObject);
begin
  CloseReports;
  if not assigned(RepMakeView) then
    RepMakeView := TRepMakeView.Create(nil);
  with RepMakeView do
  begin
    QRep.PrinterSettings.PrinterIndex := Printer.PrinterIndex;  
     QRep.Preview;
  end;
  if assigned(RepMakeView) then RepMakeView.Close;
end;

procedure TQueryList.CloseClick(Sender: TObject);
begin
  close
end;

{no changes to the CloseReports procedure - it is great}

procedure TQueryList.CloseReports;
var iTel: Integer;
begin
  try
    for iTel:= Screen.FormCount-1 downto 0 do
      if Screen.Forms[iTel].ClassName='TQRStandardPreview' then begin
        Screen.Forms[iTel].close;
      end;
  except
  end;
end;

Re:check report is closing


Thanks Colin for all the explanation

Using nil as owner seems indeed to speed up a little...
Indeed getting AV errors when having more QRStandardforms then reportforms

I need to have more then one report open, thus I cant call the closereports
before
making an new one. The user closes the report himselfs, in an order he wants
or the program closes all the report. So freeing the reports is still some
problem.
For know the reports remains in mem, later I need to look how to solf this
more.

Thanks
Werner

Quote
>Werner,

>I agree that you need to eliminate the cause of the problem so that
>you can get rid of the timer.  It is not nice to rely on that.

>I love your procedure for closing the previews.  I had something
>similar to that but yours is better.   By counting downwards, you are
>able to close all of them.

>Just a couple of comments.  If you are creating and freeing forms
>yourself, it is better to use Nil as the owner rather than Self or
>Application.   If you use Application as the owner and then free the
>form yourself, you may get an AV when the application also tries to
>free the form but it no longer exists.   On the other hand, if you let
>the application handle the freeing, then the free won't happen until
>the app. closes, so all the forms you create will be taking up memory
>and resources until then.  Using Nil as the owner also speeds up the
>closing and freeing.   There was a very good article written about
>this but I cannot remember where to find it.

>I should mention that there is also a bug in Qrprntr.pas that causes
>occasional AV's due to an uninitialised variable in the
>TQRPrinter.Print procedure.  However you need the source code to fix
>that.

>This is how I would do it.

>(A) In the FormClose event of RepMakeView, place the line:
>               Action := caFree;
>This ensures that the free doesn't happen unless and until the form is
>closed but it *does* always happen when the form is closed if the
>owner is Nil.

>(B) In the FormDestroy event of RepMakeView, place the following code.

>  if assigned(RepMakeView) then RepMakeView := Nil;

>(C) Move the call to CloseReports so that you do that before creating
>a new report.   That way there will never be more than one report and
>one preview in existence.  You then don't need to call CloseReports
>when closing the calling form (although it wouldn't do any harm if you
>did).   The problem of the preview not being freed only occurs when
>there are more previews in existence than report forms.

>procedure TQueryList.BitBtnVieuwClick(Sender: TObject);
>begin
>  CloseReports;
>  if not assigned(RepMakeView) then
>    RepMakeView := TRepMakeView.Create(nil);
>  with RepMakeView do
>  begin
>    QRep.PrinterSettings.PrinterIndex := Printer.PrinterIndex;
>     QRep.Preview;
>  end;
>  if assigned(RepMakeView) then RepMakeView.Close;
>end;

>procedure TQueryList.CloseClick(Sender: TObject);
>begin
>  close
>end;

>{no changes to the CloseReports procedure - it is great}

>procedure TQueryList.CloseReports;
>var iTel: Integer;
>begin
>  try
>    for iTel:= Screen.FormCount-1 downto 0 do
>      if Screen.Forms[iTel].ClassName='TQRStandardPreview' then begin
>        Screen.Forms[iTel].close;
>      end;
>  except
>  end;
>end;

Other Threads