Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

what does VFP do when thisform.release is executed? 4

Status
Not open for further replies.

Mandy_crw

Programmer
Jul 23, 2020
578
PH
Hi everyone... i jus want to know about thisform.release command... i have a procedure CmdExit that closes my application, and that also contains the following commands...

ThisForm.Release

CLOSE DATABASES
CLOSE ALL

i just want to ask is correct or there is a redundant command? Thanks and God bless....
 
Hi Mandy,

THISFORM.Release causes two Form events:

1) Destroy event
2) Unload event

it's a better idea to put
CLOSE DATABASES
CLOSE ALL
into the Unload event

Regards, Stefan
 
Hi Mandy,

You may want to have a look a the help file and search for "Event sequence"

hth

MarK
 
The answers you got are not wrong at all, but may not give the understanding you need.

First of all I'd state thisform.release() closes a form, no matter what else happens or is done in form code. Stefan and MarK correctly point out the events that happen when you close a form also happen in this case, but one event especially is skipped: The form.QueryuUnload() event, that allows you to check how a form is closed by checking the forms releasetype property.

So in that sense Thisform.Releases ensure the closing of the form, whereas skipping it CLOSE ALL is a command that would also close forms, but that could be hindered whereas thisform.release() can't be hindered to close the form. On the other hand CLOSE ALL closes more things than just thisform, well simply as it says, it closes all.

As Mark pointed out, it's important to know about events and their order of happening, too. CLOSE ALL sounds extreme and enough to end any tidy up everything, but you have to know indeed it could also be called "TRY" CLOSE ALL. As CLOSE ALL only can try to close all file handles, workareas, forms and maybe more I forgot. But in case of forms, for example, it still triggers events like the Destroy) event, the Unload/() event, and also QueryUnload(). And there are ways these events can stop and hinder the closing and keep a form up and open, so after CLOSE ALL there can still be forms open.

All in all, I'd say this code is okay, there's no need to change it from this perspective, because of thisform.release() taking care of releasing the form. Stefan is right, that the further commands could also be put into the form unload event as that always happens. It's a matter of taste if you therefore do split up code and have it in two places.

Overall, it's quite a complicated topic and important to know about, so a good time to study events. Especially form events, as forms have more events than other classes. For example, almost all classes (except the empty class) have an init and destroy event as the initial and last event, the form also has a load and unload on top of that, where form.load() comes even before form.init and form.unload() hppes after form.destroy(). Besides forms have the QueryUnload event, which is yet another event at the end of a form's life. Forms are very intricate about what happens in them, as they are very complex. There's the dataenvironment, too, that's actually its own object with more events all happening also in some order with the forms initial and final chain of events, too.

From a larger perspective, it would even only be a good idea to have CLOSE DATABASES ALL and CLOSE ALL in a final code that's called ON SHUTDOWN on one side and after READ EVENTS on the oher side. Because if you have multiple forms in your application, you don't want the closing of one of them close all data, that's too early and CLOSE ALL then is too rigorous anyway. So this code, if it belongs to a form at all, then only to the main form of the application that's started first and closed last.

It's actually a good idea to not put such code into forms at all, so you always have the option to extend the application further into something that may not only have one main form Maybe it would even start with only the _Screen open and a menu and what form users start is upon them.

Final closing code belongs into either a routine that's triggered by ON SHUTDOWN and then also code that runs after the READ EVENTS should call into that to "close the curtains" and do all tidy up stuff at the end of an application. And you can make that a principle and do it even in case your application only is a single-form application because it's a concern and therefore also a task of the application, not any form, not even the main form of an application. So even though you can consider the close button of a main form the close button of the application at the same time, its still mainly just the close button of the form, and the closing of the application should ideally only be a consequence of the closing of the main form, i.e. what happens after the main form has closed should tidy up and quit the process, not the form itself.

If you know more about events you'll have more insight into why developers might still opt for such solutions. The CLEAR EVENTS command, for example, that causes VFP to continue after READ EVENTS can be hindered to do exactly that by any modal state like a report preview still open. Which makes code easier, that is more rigorous, like CLOSE ALL is.

Chriss
 
Interesting note, you can alternatively use
[pre]Release thisform[/pre]



If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mandy,

In general, THISFORM.Release releases the form, but it does not necessarily close the application.

If the form is modeless (which is the usual case, and also the default), then you should have done READ EVENTS just after you opened the form. READ EVENTS has the effect of pausing the execution of your code while the user is interacting with your application. If READ EVENTS wasn't there, the program (the one that launched the form) would continue to run, and would eventually exit, the effect being that the user would never see the form. READ EVENTS prevents that from happening.

When you are ready to exit the application, you need to execute CLEAR EVENTS. That has the effect of cancelling the READ EVENTS, thus allowing the program to close. You would normally put CLEAR EVENTS in whatever button or menu option the user uses to signal that they want to close down - in this case, the cmdExit button.

So, to answer your question, your cmdExit.Click should contain:

Code:
THISFORM.Realease
CLEAR EVENTS

As for closing the database and tables, that is not essential as they will be closed automatically when the application closes. But it will do no harm to do it explicitly.

Hope this helps.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
There's a lot more to get from all of this, for example regarding saving data changes. As I said the QueryUnload event is skipped whenever you directly release a form, so the code that does call Thisform.Release() should first ensure there are no buffered changes still unsaved, or you could get into a situation those changes cause the datasession to persist and continue to exist, while the form is closed. It may even hinder the form to end, actually.

One way to take this into account is being cautious and setting flags whenever changes are made. One way is to set the forms closable property to .f. and only set it back to .T. once changes are saved. See your other recent thread with MarKs example of how to handle saving changes with buffering, using TABLEUPDATE() and GETNEXTMODIFIED().

We're on the territory of preferences, here, though, because many prefer a forms close button (the X at the top right corner of the form title bar) to not get disabled. Instead, the user should be able to click, but when he does close the form, the form should first check, whether unsaved buffered changes exist. To react to the user clicking the X button ou have to use the QueryUnload event, as that what is triggered first. But, as is our problem, it's not executing, if you do thisform.release().

On one side it's frustrating for a user to not be able to use standard buttons like the X close button and not knowing why, on the other side allowing that and not programming anything for the case a user prematurely tries to close a form, that's causing the same trouble again, a lingering datasession hindering the form to end. And then, once more, it's unfortunate that you can only react in the QueryUnload, which is skipped, if you force the release of the form.

All in all, VFPs architecture makes it hard to implement a simple mechanic as the forced release can skip a QueryUnload. And doing a check for unsaved changes in the forms destroy or unload is too late, actually. Those are the problems to think about. This is spanning a web of problematic cases you have to navigate with your form code and it's not easy.

Chriss
 
Hi Mandy,

You may also want to open the debugger window (Tools - Debugger), click the icon "Toggle event logging", choose the events you want to track, click "Turn on event tracking". Then run a program (e.g. thread184-1824310), close it and follow the event sequence.

hth

MarK

 
Thanks everyone for you enlightenment... ive read all your very comprehensive explanations.... Thanks and God bless....
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top