PlanetSquires Forums

Support Forums => Other Software and Code => Topic started by: Paul Marsh on August 08, 2005, 05:57:23 AM

Title: Shutting Down Programs when Window is Closed
Post by: Paul Marsh on August 08, 2005, 05:57:23 AM
I'm pretty new to Windows programming but am finding Firefly invaluable for quickly producing small applications for in-house use where I work.

One problem I'm having is understanding how to shut down a program with the "Close" button or Alt-F4 without it remaining memory. I seem to have inconsistent results in this area.

One of my latest "quick and dirty" applications consists of a simple loop instigated by a button control after data is entered on the form. A second button control is used to set a global variable which escapes the loop and closes the program neatly. The problem I have with this application is that if, once the loop is running, a user closes it with the "Close " button or Alt-F4, I cannot find anywhere to set my global and shut the program down fully. WM_CLOSE and WM_DESTROY don't seem to work.

In a previous, more complex, program I found that setting the global to stop the loop in WM_CLOSE seemed to do the trick and I was able to close two loops in different threads without any problem. The only difference was that the main loop was started in FF_WinMain in this case. Is this significant?

I have found a couple of mentions of similar problems in these forums but I'm really no closer to understanding how to effectively shut down a program if a user simply closes the form.

Any insight will be appreciated.
Title: Shutting Down Programs when Window is Closed
Post by: TechSupport on August 08, 2005, 10:58:02 AM
Hi Paul,

I think that you should respond to the WM_SYSCOMMAND message. The code below should be a good guide for you.

'------------------------------------------------------------------------------------------------------------------------
Function FORM1_WM_CLOSE ( _
                       hWndForm As Dword _  ' handle of Form
                       ) As Long

       MsgBox "wm_close has been fired... Change your global flag here."
End Function


'------------------------------------------------------------------------------------------------------------------------
Function FORM1_CUSTOM ( _
                     hWndForm      As Dword, _  ' handle of Form
                     wMsg          As Long,  _  ' type of message
                     wParam        As Dword, _  ' first message parameter
                     lParam        As Long   _  ' second message parameter
                     ) As Long


  If wMsg = %WM_SYSCOMMAND Then
     Select Case As Long ( wParam And &H0FFF0 )
       Case %SC_CLOSE                            
           PostMessage hWndForm, %WM_CLOSE, 0, 0
           Function = %TRUE
     End Select
  End If  

End Function
Title: Shutting Down Programs when Window is Closed
Post by: Roger Garstang on August 09, 2005, 01:43:59 AM
Doesn't FF already post the WM_CLOSE message from WM_SYSCOMMAND in the code it generates internally for the app?  I've been using it for some time now to just process WM_CLOSE since FF routes it all to one message.

The problem he is having though isn't because of that, it is the loop causing it.  Especially when the loop is in the message handler or called from the message handler which most are.  Something about the way the window gets destroyed by Windows.  Even if you have a loop test for the window to exist, etc it still seems to stay running cause the loop was going when the message handler exited.

Only solution I've found is I made a Global I called Running.  When it is 0 then it isn't running, when it is 1 it is running, when it is 2 the user has pushed the cancel/abort button, and I usually make 3 the Close case...although it could be the same as 2 if you have an "Are You Sure You Want to Abort" prompt it works on Close.  Then in WM_CLOSE if Running > 0 then I set it to 3 (or 2) and abort the close (Return TRUE).  That way the loop isn't running on close...otherwise as he reported it appears to close, but the process is still there.  Another reason to use 3 is you can then test after aborting the loop for if it was 3 and they agreed to abort you can then PostMessage a WM_CLOSE...after setting Running to 0 of course, otherwise it will be aborted.
Title: Shutting Down Programs when Window is Closed
Post by: Paul Marsh on August 09, 2005, 06:13:17 AM
Thanks for the replies guys.

Roger,
I was just about to reply to Paul (Squires) this morning to say that his suggestion hadn't worked when I tried it last night and that it didn't seem to make any difference whether the WM_SYSCOMMAND message was intercepted or not.

Thanks for your explanation. I had read your solution in a previous post but hadn't really been able to figure it out. It's beginning to make more sense to me now but I think my problem is that I haven't yet discovered how to intercept the "Close" button. Thanks for the pointers - I'd like to get this sorted as it seems such a fundemental requirement for any program.
Title: Shutting Down Programs when Window is Closed
Post by: Paul Marsh on August 09, 2005, 09:01:10 AM
OK guys ... the "penny has finally dropped" ** and everything becomes clear!

In fact what I wanted to achieve turned out to be a hybrid of your two solutions. I feel in control again!

Thanks - these forums are a great way to learn.

(** quaint English expression)
Title: Shutting Down Programs when Window is Closed
Post by: Roger Garstang on August 10, 2005, 01:11:53 AM
Cool, glad it worked.  What I was saying about %WM_SYSCOMMAND is I think in the finaly generated code, like the .bas file for the form you are working with...usually there is a MAIN file, etc in the sorce folder...I believe FF already puts that code there.  So, you should be able to intercept everything in WM_CLOSE.  %WM_SYSCOMMAND is the code for the system menu, WM_CLOSE is for things like ALT+F4, etc.  So, by having the %WM_SYSCOMMAND code there it puts both through WM_CLOSE.