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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Alter CloseBox to minimize form 2

Status
Not open for further replies.

JackTheC

Programmer
Feb 25, 2002
325
NL
Hi Guys,

I thought this was something easy: alter the behaviour of the Close box, the "X" in the upper right corner of a form.
I want to minimize the form instead when the user clicks the X (or maybe do something else no matter what).
I have a Quit button elsewhere on the form with a "Release Thisform" command.

I put this in the QueryUnload event.
Code:
thisform.windowstate=1  && minimized
nodefault

That works fine. The problem however is the Nodefault instruction.

When the user selects "Close Window" in the popup menu on the taskbar icon of my program, Windows evokes the QueryUnload event too, resulting in Nodefault and a lot of strange things happen, like a grid that becomes empty. Or when I Shutdown Windows while the app is still running, It shows up as "A program preventing the shutdown".
I want Windows to be able to nicely shutdown the running application, which works great when nodefault is not used in QueryUnload....

So how to make QueryUnload aware of the difference between an users X click or Windows closing the app?
Or is there any other way to alter the behaviour of the Close button (or Alt+F4) by not using QueryUnload?
And Yes I know I can set CloseBox to .f. te prevent the user clicking at all, but that is not what this question is about.

B.t.w. this is a simplefied main.prg example:

Code:
ON SHUTDOWN do quitform   && does a clear events and a release windows
do form testclos
read events
ON SHUTDOWN
 
Hi JackTheC,

just track the mouse coordinates and the last key pressed!

Put this code in Your QueryUnload event:

Code:
colVal = MCOL( THISFORM.Name, 3 )
rowVal = MROW( THISFORM.Name, 3 )

keyVal = LASTKEY()

DO CASE
    CASE keyVal = 107                     && Alt+F4
*       Your code ...

    CASE colVal = -1 AND rowVal = -1      && Taskbar: Close Window
*       Your code ...

    CASE colVal != -1 AND rowVal = -1     && Close Box
        THISFORM.WindowState = 1
        NODEFAULT

    CASE colVal = -1 AND rowVal != -1     && System Menu: Close
*       Your code ...

*   just other CASEs ???
*       Your code ...

ENDCASE

Regards, Stefan
 
Hi Jack,

Stefan's code should work, but I believe there is an easier way:

In your QueryUnload, check the setting of the form's ReleaseType property. A setting of 1 means that the use is trying to close via the X button or control menu. Other settings indicate that the user is closing the app, or shutting down Windows.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mike,

it's really unbeleavable - I am using VFP since 1997, but I never noticed the ReleaseType property !!!

I'm really speechless . . . you never stop learning :)

Thankx, Stefan
 
Thanks Stefan and Mike for your quick responses.

Stefans code works fine. But not always. Sometimes, and that is coincendence, it does not run properly.

The close command in the Systemtray button depends on the colVal and rowVal values. When the values are -1 and -1 it works great.
That means the mouse row is below the form and the mouse column before or behind the form.
But there is a problem when the form is above the taskbar button or the form is maximized. Than the column value <> -1 and the Minimize instructions are executed. (But not always....)

And Mike, the ReleaseType always seems to be 1 even when Windows shuts down, except after the error described above.
I noticed that both 1 and 2 (in that order) are assigned in case of a Windows shutdown.
 
When Windows shuts down you get a SHUTDOWN event, you can predefine what reacts to it with ON SHUTDOWN somecall() in the same manner as you can define error handling with ON ERROR errhandling(). You might do something signaling a windows shotdown, eg create a public variable, then QUIT, but ReleaseProperty should be 2, if the VFP mainform/_SCREEN close button is used or windows shuts down.

You create a very unusual interface this way, if you want to disable closing a form, then simply disable the X, set form.closable=.F., to minimize the form there is a minimize button, isn't there?

Bye, Olaf.
 
@Olaf, I already mentioned "And Yes I know I can set CloseBox to .f. te prevent the user clicking at all, but that is not what this question is about."

But suppose I want to ask the user "Are you sure you want to close this form?" using a messagebox instead of a minimize...
Same problem. I want to determine the way the close command is issued. Stefan code is a beginning, but does not work properly when the form is in maximized state.

 
Concentrate on the ReleaseType Property. I can't reproduce what you say about it always being 1, when windows shuts down, but I gave another solution to know for sure.
You also know and use ON SHUTDOWN. One thing to know: Even if you QUIT, all forms QueryUnload events still run. ReleaseType then should be 2 as for windows shutdowns. You may not get ReleaseType being set to 2, because you do a routine quitform. If that releases a form via form.Release or by releasing a variable holding the form reference, you don't get ReleaseType=2, yes. The simplest use of ON QHUTDOWN is ON SHUTDOWN QUIT.

Bye, Olaf.




 
But suppose I want to ask the user "Are you sure you want to close this form?" using a messagebox instead of a minimize...

Well, in that case, I suggest you do want the same behaviour, regardless of the way in which the user is closing the form. Aftre all, if the form has unsaved edits, and you want to warn the user that the edits will be lost if the form is closed, then that would apply equally whether the user is clicking the X, or closing the app, or closing Windows, or whatever.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I agree with Mike in that aspect. Open Notepad, type something, keep it unsaved and shut down windows. It'll also display a question. But I'm afraid Mike, this is still not the final goal, Jack keeps this to him, because the reasoning might be too complicated to explain.

Bye, Olaf.
 
And Mike, the ReleaseType always seems to be 1 even when Windows shuts down, except after the error described above.
I noticed that both 1 and 2 (in that order) are assigned in case of a Windows shutdown.

That's not what I am seeing.

I see ReleaseType = 1 when you:

- Close the form from the X;

- Close the form by selecting Close in the control menu.

I see ReleaseType = 2 when you:

- Execute Quit;

- Close the app from the X (that is, the app's Close button, not the form's);

- Close the app by selecting Close on the taskbar button's context menu;

- Shutdown Windows.

I don't see any cases where you get "1 and 2 (in that order)". That would suggest that you are calling QueryUnload twice, which in turn suggests that your code is more complicated than you have indicated. The presence of NODEFAULT might be causing something unexpected. In particular, NODEFAULT in QueryUnload will cancel a Windows shutdown.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Yes Mike the Nodefault is causing the problem.

That is because I can't yet determine whether the user has clicked the red X closebox on the form or
had chosen Close Window from the taskbar right click menu.

I used Stefans code. if the user clicks the red X then colVal<> -1 and rowVal= -1 evoking Minimize and Nodefault.

But if the user chooses Close Window from the taskbar then depending on the form position and size in relation to the taskbar button, the same kind of values are assigned. So the QueryUnload event thinks the user clicked the closebox and performs a nodefault. But VFP is still closing tables. A mess yet to unravel.

If the form is NOT above the taskbar button it all works well since the colVal is then -1.
 
Would it help if you could detect the absolute mouse position, rather than the position relative to the VFP window?

In Stefan's code, you can detect if the mouse is outside the VFP window (by testing for -1), but, as you have found, that doesn't necessarily mean that it is on the taskbar.

In thread184-1028351, there is some code that will show you how to determine the absolute mouse position (see the second-to-last post in that thread). That might put you in the right direction. Although you might also need to know on which side of the screen the taskbar is docked.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
>On shutdown quit, when Windows closes the app, is worse. The normal end and cleanup routines are not executed.

That's wrong.
A QUIT causes all running Forms QueryUnload. With ReleaseType being 2

Code:
ON SHUTDOWN Quit

PUBLIC goApp, goMainForm
goApp = CREATEOBJECT("myapp")
goMainForm = CREATEOBJECT("myform")
goMainForm.Show()
Read Events

DEFINE CLASS myapp as Custom
   PROCEDURE Destroy()
      ? "Bye from the app"
      MESSAGEBOX("Bye bye!") && just so all the messages can be seen
   ENDPROC 
ENDDEFINE 

DEFINE CLASS myform as Form
   width=600
   PROCEDURE queryunload()
      IF This.ReleaseType=2
         ACTIVATE Screen
         ? "Bye from the main form"
      ELSE
         ? "No, I'm not going to quit. Quit by close button of the screen"
         nodefault  
      Endif
   ENDPROC 
ENDDEFINE

This clearly shows things happening after the quit you cause by closing the screen.
An additional test for you: Do QUIT instead of READ EVENTS and the same thing happens.

Bye, Olaf.
 
That's right Mike. Thanks. While biking this afternoon I got the same idea. In Stefans routine, when mcol<>-1 and mrow=-1 check the absolute Y coördinate to see whether it is near the bottom of the screen (taskbar) or not (closebox). That works.

 
Hi JackTheC,

there is still one little problem to solve!

- the taskbar can be below or above or left or right of the desktop (OK, mostly below)

Regards, Stefan
 
Here's some code that determines if the taskbar is at the top, right, bottom or left of the screen:


I'm not sure if this will work if you are running across multiple screens (the taskbar doesn't have to be on the primary screen).

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top