QB64 Phoenix Edition
DAY 029: _EXIT - Printable Version

+- QB64 Phoenix Edition (https://staging.qb64phoenix.com)
+-- Forum: Official Links (https://staging.qb64phoenix.com/forumdisplay.php?fid=16)
+--- Forum: Learning Resources and Archives (https://staging.qb64phoenix.com/forumdisplay.php?fid=13)
+---- Forum: Keyword of the Day! (https://staging.qb64phoenix.com/forumdisplay.php?fid=49)
+---- Thread: DAY 029: _EXIT (/showthread.php?tid=1257)



DAY 029: _EXIT - Pete - 12-10-2022

Not to be confused with _BREXIT, which was a useful keyword to get the hell out of the E.U., _EXIT is a useful keyword to get you out of trouble if you mistakenly click the "X" symbol before parts of your app have completed, like writing to a very large file.

SYNTAX:  var% = _EXIT

Values are as follows...

Code: (Select All)
' "x"......... 1
' Alt + F4.....1
' Ctrl + Break 2
DO
    a% = _EXIT
    PRINT a%
    _LIMIT 1
    IF INKEY$ = CHR$(27) THEN END
LOOP

_EXIT covers all exit routines, which is why I put that INKEY Esc to end line in the code; otherwise, you'd have to shut it down with Task manager.

So, what's it good for? Well, let's say your cat walks into the room, jumps on your mouse and sits its kitty-butt down on the left mouse button. Well wouldn't you know it, the mouse pointer is positioned on the "x" and the program is running a pi algorithm that has been going on for days! Well, before you think about getting rid of your cat, and getting a life, try _EXIT in your program instead; here's how...

Code: (Select All)
DO
    FOR i = 1 TO 10
        ON _EXIT GOSUB pete ' Pauses this count routine when the "x" is clicked.
        PRINT i
        _DELAY .5
    NEXT
LOOP UNTIL LEN(INKEY$) ' If you press a key, it will end after it prints "10".
END

pete:
LINE INPUT "Are you sure you want to quit? Y/N: "; ans$
IF LCASE$(ans$) = "y" THEN SYSTEM
RETURN


So you might ask, hey Pete, why'd you put the _EXIT command in the FOR LOOP, instead of the DO LOOP? And I'd reply, so the user doesn't think the "x" close program function is broken.

Now let's try it in the DO LOOP, and see what happens...

Code: (Select All)
DO
    ON _EXIT GOSUB pete ' Pauses this count routine after count "10".
    FOR i = 1 TO 10
          PRINT i
        _DELAY .5
    NEXT
LOOP UNTIL LEN(INKEY$) ' If you press a key, it will end after it prints "10".
END

pete:
LINE INPUT "Are you sure you want to quit? Y/N: "; ans$
IF LCASE$(ans$) = "y" THEN SYSTEM
RETURN

So we click "x" after it prints 2 or 3, whatever... and it keeps counting. Go ahead, click the hell out of "x", it won't matter. It isn't going to move to the sub-routine until it finishes the FOR LOOP.

Now you could do worse, and put it outside the DO LOOP. This disables the "x" quit function, but keeps the click in memory. That's a problem as our program is supposed to "END" with the screen still up and a, "Press any key to continue." message at the bottom. Oops, that click in memory kills the window!

So knowing what effect you want and where to place the _EXIT command is important. For instance, let's say it was imperative we get that FOR LOOP to complete before we quit. I'd say code a warning message something like this...

Code: (Select All)
DO
    stopexit = -1
    FOR i = 1 TO 10
        ON _EXIT GOSUB pete
        PRINT i
        _DELAY .5
    NEXT
    IF stopexit = 0 THEN END
    PRINT "You have 10 seconds to exit before the next loop begins..."
    stopexit = 0
    z1 = TIMER
    DO: ON _EXIT GOSUB pete: LOOP UNTIL ABS(TIMER - z1) >= 10
LOOP UNTIL LEN(INKEY$) ' If you press a key, it will end after it prints "10".
END

pete:
SELECT CASE stopexit
    CASE -1
        PRINT: PRINT "Okay, the program will end after it prints to 10.": PRINT: _DELAY 3
        stopexit = 0
    CASE 0
        SYSTEM ' But Yogi, won't exiting before returning cause a stack space leak? I don't give a **** Booboo.
END SELECT
RETURN

So in review, _EXIT returns 1 for "x" in the window or in the task bar projection, 1 for Alt + F4, and 2 for Ctrl + Break. Where you place it determines the behavior, either immediate or delayed action, and be sure to use a key routine or sub-routine to bail yourself out so you don't have to resort to Task manager to suspend the program window.

<--- Pete _EXIT stage left...


RE: DAY 029: _EXIT - SMcNeill - 12-10-2022

I've found _EXIT is one of the few commands that I'll put in an ON TIMER sub or event.  That way, no matter what my program is doing, every .05 second or so, it checks very fast for an _EXIT event.

What's the main purpose of an _EXIT routine??

To make certain you save any data before the program closes!

Say you've created an enhanced clone of notepad.  You spend 8 hours writing the great American novel in it.  You sneeze, accidentally clicking the bright red ❌ in the top right corner.  AHHHHHHHHHH!!  All that work just....  gone...

/cry

I bet you now wished you'd taken time to write a little routine to dump your file to disk before shutting down and closing!

THAT is what _EXIT works perfectly for!!

IF _EXIT THEN
   BackUpMyJunk
   System
END IF


RE: DAY 029: _EXIT - vince - 12-10-2022

nice prose, Pete, it's no Steve but thanks for filling in


RE: DAY 029: _EXIT - Pete - 12-10-2022

Good point Steve!

I have that on my WP app. "Save file before exiting?" It runs in a continuous flow-through loop, so it is always checking for _EXIT.

--------------------------------

BTW - It is worth noting that CLEAR does not affect _EXIT and there is no _EXIT OFF. To get your program back to quitting when the "x" is clicked requires adding a sub-routine like in the above examples, which evokes the SYSTEM statement.

Pete


RE: DAY 029: _EXIT - Pete - 12-10-2022

(12-10-2022, 07:10 AM)vince Wrote: nice prose, Pete, it's no Steve but thanks for filling in

                                                                                  ^
You missed your period. You might want to consider a home pregnancy test.

No Steve... Tongue

Pete


RE: DAY 029: _EXIT - mnrvovrfc - 12-10-2022

(12-10-2022, 05:41 AM)Pete Wrote: _EXIT covers all exit routines, which is why I put that INKEY Esc to end line in the code; otherwise, you'd have to shut it down with Task manager.
This is a keyword to be told: newbie beware! "Experienced" BASIC coder included! It's because so much code for QBasic, for example, doesn't even have [ESC] or any other key to clean up and exit the program. It's because some people absolutely hate, "Are you sure you want to quit?" prompts from professional applications. One of those people doesn't think about filing a lawsuit and the other side just wanted to play it safe with that question message box that irritated him/her.

If "_EXIT" is not properly used, it could cause a lot of frustration. In the least, the programmer could clench his/her firsts for a few seconds then open Task Manager and kill his/her own program in memory. "Doing this could cause system instability," Windows could bark back but he/she doesn't care when he/she wants to be in complete control. Yet too lazy to program "INKEY$ = CHR$(27)" or something alike, too lazy to check string input for an empty string, too lazy to decide for one corner of the desktop screen the mouse pointer could be driven into... ever heard of GNOME yet? Rolleyes

One thing I found strange about Unix/Linux is that "kill" terminal command, in its default behavior, does not remove a process from memory. It sends a signal which is like, "Please go away" or "You need to get the eich off!" Sometimes the offended program is inclined to obey. Oftentimes the offended program finds a seg-fault and ends that way.

Yes, it happened to me, and I didn't like it. I much preferred programming for [ESC] keypress and did that since I was stuck using QuickBASIC on Windows7. It boggles me that someone who is very popular on these forums had to teach me [ALT][F4] and keeps getting away with not programming a check for an "exit keystroke" and with not using "_EXIT"... but I could be wrong.

@Pete I thought you were strictly a Looney Tunes guy, now you reminded me of the most ridiculous Hannah-Barbera could get with their cartoons...


RE: DAY 029: _EXIT - Pete - 12-10-2022

Sure, when I post snippets, at times I don't put in an exit key, because it isn't needed. The user can just Alt+F4, Ctrl + Break, or, of course, the easiest method, click the "x".

Now I don't put _EXIT in snippets because I haven't posted anything that exiting prematurely would adversely affect. Full programs like my WP, of course, have it.

I also don't post _FULLSCREEN programs, but if I did, I would throw an esc key sequence in, because often times I have had to deal with trying someone's code and needed to do ALT + Enter a couple of times to get the program in window mode, so I could shut it down.

Best line by a stand up comic in the 1980's... "But Yogi, won't the ranger be mad if we steal his picnic basket? I don't give a f*** Booboo." I blame it on the invention of wine coolers, which became popular fare for picnic baskets.

Pete


RE: DAY 029: _EXIT - mnrvovrfc - 12-14-2022

Maybe it could be fixed with "$CONSOLE:ONLY". Otherwise, the "dummy console" that is the result of "SHELL", while summoning another program, might be subject to "_EXIT" to prevent the user from "accidentally" killing the other program or causing the other program to hang. This is critical on Linux in which sometimes an app is launched from the terminal. If the terminal is closed, so is the program that is launched from it.

I should have tested that the short while I was on Windows, errr...



At least it works for me on Manjaro KDE:

Code: (Select All)
dim q as long
print "Please wait while I launch Mozilla's monster..."
q = _EXIT
SHELL _DONTWAIT "firefox"

print "Press [ESC] to exit."
print: print
do
    _limit 100
    q = _EXIT
    if q > 0 then
        print "No you may *not* exit in this way! Please press [ESC] instead!"
        print: print
    end if
    ke$ = inkey$
loop until ke$ = chr$(27)

But it's not the "SHELL" function, yes I know.

Funny that I got this message on terminal after this user program ended:

Code: (Select All)
ATTENTION: default value of option mesa_glthread overridden by environment.

EDIT: AAARGH! Got outfoxed by the one I was trying to outfox. I tried taking off the "_DONTWAIT" from the code above. Briefly it gave the message that it was going to start Firefox. Once that app was in place, however, the user program window suddenly turned into a clear lighter black with nothing in it. Pressing "X" in the top-right corner of that window did nothing. Taking away "_EXIT" produced the same behavior. Except with this user program, after I closed Firefox the user program window did respond and refused to allow clicking the icon to close the window and program, had to press escape key.


RE: DAY 029: _EXIT - Pete - 12-14-2022

It acted as it was supposed to in the remove _DONTWAIT try. Without _DONTWAIT, the app was waiting not just for Firefox to start, but to close. By having the first _EXIT, which you don't need, btw, it made it impossible to shut that window with the "x". I don't know why in Linux the window took on an unresponsive appearance. In Windows, it would jut wait until you closed Firefox.

Hey guys, here is another one for the books...

SHELL "Notepad" ' Waits for notepad to close before the calling window ends.

SHELL "Start Notepad" ' Doesn't wait!

Pete