Click here to Skip to main content
15,916,378 members
Articles / Programming Languages / Visual Basic
Article

Find out what's closing your application

Rate me:
Please Sign up or sign in to vote.
4.17/5 (5 votes)
15 Oct 2002 105.8K   25   15
Code in VB.NET to find out what's closing your application.

Introduction

You can use this code to see why your application is closing (closed by user, by Windows, by code?). It can be very handy if you are using a NotifyIcon in your app. You can figure out if the user is closing your app or not, if so, then you can just minimize it to tray.

For those who have used Visual Basic before, you know that there was a QueryUnload method for your Forms and that you could find out the reason for the form's closing by examining the UnloadMode variable.

This code snippet shows you how to do this in .NET. The sample code is in VB.NET. The code is from GotDotNet message boards, written by "YeahIGotDotNet".

VB
Private Sub Form1_Closing(ByVal sender As Object, _
  ByVal e As System.ComponentModel.CancelEventArgs) _
  Handles MyBase.Closing
    Dim O As System.Diagnostics.StackTrace = _
           New System.Diagnostics.StackTrace(True)
    Dim F As System.Diagnostics.StackFrame

    F = O.GetFrame(7)

    Select Case F.GetMethod.Name.ToString
        Case "SendMessage"
            MsgBox("Closing because of call in code.")
        Case "CallWindowProc"
            MsgBox("Closing because of system menu click.")
        Case "DispatchMessageW"
            MsgBox("Closing because of Task Manager.")
        Case Else
            MsgBox("Don't Know why I'm closing!!??")
    End Select
End Sub

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralHandles Mybase.closing Pin
atogwe11-Jun-07 8:04
atogwe11-Jun-07 8:04 
GeneralUsing WM_QUERYENDSESSION to detect Windows shutdown Pin
rodgerc2-Oct-06 8:13
rodgerc2-Oct-06 8:13 
GeneralOverriding WndProc changes the GetMethod.Name properties Pin
HanreG7-Nov-03 2:15
HanreG7-Nov-03 2:15 
GeneralCoversion of C++ method Pin
BogBrush Zone31-Aug-03 4:12
BogBrush Zone31-Aug-03 4:12 
GeneralMore complete implementation Pin
JasonSmith28-Oct-02 8:23
JasonSmith28-Oct-02 8:23 

I don't really have time to write an article on this, but here is a more complete implementation. I have tested on Windows 2000 only, so it may not work on 98/ME. Also, this has not been tested with MDI children or parents.

Most times, you need to know if you are closing because the user selects "Close" from the menu, or whether it is some sort of system thing. The previous implementation does not take into account shutting down the computer. In this instance, where I am cancelling and hiding if it is user input, this would abort the shutdown! You'd never be able to shutdown your computer normally as long as your .NET program is running.

private enum ClosingSource
{
    Unknown         = -1, //We've never seen this one before!!!
    Code            = 0,  //Shutdown from a call to this.Close();
    TaskManager     = 1,  //Shutdown from the task manager. 
    SystemShutdown  = 2,  //Windows is shutting down, or user logging out.
    FormControlMenu = 3   //User selected by clicking "X" in form, or from
                          //    the control menu.
}

private ClosingSource GetClosingSource(StackTrace stack)
{
    StackFrame frame7 = stack.GetFrame(7);
    if(frame7.GetMethod().Name == "SendMessage")
        return ClosingSource.Code;
    else if(frame7.GetMethod().Name == "DispatchMessageW")
        return ClosingSource.TaskManager;
    else if(frame7.GetMethod().Name == "CallWindowProc")
    {
        //At frame 7, a close due to system shutdown still looks
        //like a user-selected shutdown, so we have to check the
        //next change, which is at stack position 14.
        StackFrame frame14 = stack.GetFrame(14);
        if(frame14.GetMethod().Name == "WndProc")
            return ClosingSource.SystemShutdown;
        else if(frame14.GetMethod().Name == "WmSysCommand")
            return ClosingSource.FormControlMenu;
    }
			
    return ClosingSource.Unknown;
}

private void EventLog_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    StackTrace stack = new StackTrace(true);

    ClosingSource source = GetClosingSource(stack);

    if(source == ClosingSource.FormControlMenu)
    {
        e.Cancel = true;
        this.Hide();
    }
}

I don't like the stack-based solution for "QueryUnload" --> "Closing" much. It depends on a lot of underlying code that I don't have any control over not changing over time. However, I have yet to find a better method, or even another method that works. One of the few instances where .NET functionality is not a superset of VB6.


GeneralClosing a User Control Pin
Peter S16-Oct-02 6:06
Peter S16-Oct-02 6:06 
GeneralRe: Closing a User Control Pin
David Stone16-Oct-02 14:55
sitebuilderDavid Stone16-Oct-02 14:55 
GeneralRe: Closing a User Control Pin
BarryJ16-Oct-02 20:09
BarryJ16-Oct-02 20:09 
GeneralRepost Pin
Richard Deeming13-Oct-02 23:05
mveRichard Deeming13-Oct-02 23:05 
GeneralRe: Repost Pin
Anonymous14-Oct-02 14:13
Anonymous14-Oct-02 14:13 
GeneralRe: Repost Pin
Richard Deeming14-Oct-02 22:40
mveRichard Deeming14-Oct-02 22:40 
GeneralRe: Repost Pin
Anonymous14-Oct-02 18:36
Anonymous14-Oct-02 18:36 
GeneralRe: Repost Pin
Richard Deeming14-Oct-02 22:47
mveRichard Deeming14-Oct-02 22:47 
GeneralRe: Repost Pin
MrPolite16-Oct-02 12:22
MrPolite16-Oct-02 12:22 
GeneralRe: Repost Pin
Richard Deeming16-Oct-02 23:02
mveRichard Deeming16-Oct-02 23:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.