Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 6 of 6 total
Thread Why Cannot Call Close Twice?
Thu, May 2 2019 4:42 AMPermanent Link

Frederick Chin

I have the following code for OnCloseQuery. For some reason, OnCloseQuery will not fire and display my ShowMessage() twice when I call the form's Close procedure and global variable lSomeThingDone is False.

Variables lCloseResult and lSomethingDone are True and False respectively when the Close is called initially.

Am I missing something obvious here?

function TfrmReports.frmReportsCloseQuery(Sender: TObject): Boolean;
begin
  showmessage(IntToStr(nEscape));  // This line not called twice
  if lCloseresult then begin
     if not lSomethingDone then begin
        Result:=False;
        doclosetest;  
       end
     else
        Result:=True;
    end
  else
     Result:=False;
end;                      

procedure TfrmReports.DoCloseTest;
begin                  
  inc(nEscape);
  lSomethingDone:=True;
  close;
end;

--
Frederick
Thu, May 2 2019 5:33 AMPermanent Link

Matthew Jones

This was discussed by me recently - the key is that your showmessage is not blocking, so the rest of the code continues to run before it is actually shown to the user. In essence, you have to stop it, and then ask the user.


--

Matthew Jones
Thu, May 2 2019 7:33 AMPermanent Link

Frederick Chin

"Matthew Jones" wrote:

/*
This was discussed by me recently - the key is that your showmessage is not blocking, so the rest of the code continues to run before it is actually shown to the user. In essence, you have to stop it, and then ask the user.
*/

I do understand that the code will continue to run even with the ShowMessage(). However, even if I remove it, the OnCloseQuery event still does not fire a second time.

I have to click the Close button again before the form will close.

The ShowMessage calls should not affect the closing of the form since the ShowMessage() is non-modal.

--
Frederick
Thu, May 2 2019 10:40 AMPermanent Link

Frederick Chin

I got it working by prefixing the Close call with the Async keyword and I am not quite sure why it should work.

function TfrmReports.frmReportsCloseQuery(Sender: TObject): Boolean;
begin
 showmessage(IntToStr(nEscape));  // This line is now called twice
 if lCloseresult then begin
    if not lSomethingDone then begin
       Result:=False;
       doclosetest;  
      end
    else
       Result:=True;
   end
 else
    Result:=False;
end;                      

procedure TfrmReports.DoCloseTest;
begin                  
 inc(nEscape);
 lSomethingDone:=True;
 async close;        // Added here
end;

--
Frederick
Thu, May 2 2019 3:23 PMPermanent Link

Raul

Team Elevate Team Elevate

On 5/2/2019 10:40 AM, Frederick Chin wrote:
> I got it working by prefixing the Close call with the Async keyword and I am not quite sure why it should work.
>
>    async close;        // Added here
> end;

Your code was re-entrant - you're basically calling :

Close -> frmReportsCloseQuery -> DoCloseTest -> Close

EWB internally (see TFormControl.Close in webforms) sets a flag
"FClosing" and does not call CloseQuery twice so you need to have
CloseQuery return first.

Doing async will fix this since it queues the execution of close to the
next exceuption loop allowing initial frmReportsCloseQuery to exit and
FClosing  to be reset before Close is called again so it' basically

Close -> frmReportsCloseQuery -> DoCloseTest

and then at next execution loop

Close

Raul
Thu, May 2 2019 6:26 PMPermanent Link

Frederick Chin

Raul,

Thank you for the explanation.

I stuck the async call in at a whim and I am glad that it worked since I spent a couple of hours trying all types of things to try to resolve the problem.

--
Frederick
Image