Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Overriding the Closing event

Overriding the Closing event

Scheduled Pinned Locked Moved C#
helpcsharpquestion
8 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    I have written a C# windows application. However, when the program is running, and I want to shut down windows, every program closes except my C# program; and windows does not shut down. It just waits. When I close my program manually, windows shuts down without a problem. The cause is that I have overriden the Closing event of the main form like this: private void WindowsCloserForm_Closing(object sender, System.ComponentModel.CancelEventArgs e) { e.Cancel = true; OpenDialog(false); } I wanted this behaviour however: closing the form should not end the program, but just hide it. (Via an icon in the system tray you can close the program) If I do not override the Closing event, this problem does not occur. Can this be a bug in the framework, or am I forgetting something? Ludwig

    D 1 Reply Last reply
    0
    • L Lost User

      I have written a C# windows application. However, when the program is running, and I want to shut down windows, every program closes except my C# program; and windows does not shut down. It just waits. When I close my program manually, windows shuts down without a problem. The cause is that I have overriden the Closing event of the main form like this: private void WindowsCloserForm_Closing(object sender, System.ComponentModel.CancelEventArgs e) { e.Cancel = true; OpenDialog(false); } I wanted this behaviour however: closing the form should not end the program, but just hide it. (Via an icon in the system tray you can close the program) If I do not override the Closing event, this problem does not occur. Can this be a bug in the framework, or am I forgetting something? Ludwig

      D Offline
      D Offline
      David Wengier
      wrote on last edited by
      #2

      This thread should have an answer: Click here -- David Wengier Sonork ID: 100.14177 - Ch00k

      L 2 Replies Last reply
      0
      • D David Wengier

        This thread should have an answer: Click here -- David Wengier Sonork ID: 100.14177 - Ch00k

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        I'm sorry, I didn't remember I already asked this question in this place. I'll try it out...

        1 Reply Last reply
        0
        • D David Wengier

          This thread should have an answer: Click here -- David Wengier Sonork ID: 100.14177 - Ch00k

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Well, I tried: override protected void WndProc(ref Message m) { int message = m.Msg; if ( message == 0x0012 ) //WM_QUIT { } else if ( message == 0x0010 ) //WM_CLOSE { // Who closed the form? } base.WndProc(ref m); } but is seems that quitting windows does not raise the WM_QUIT event. It raises the WM_CLOSE event, though. But how can I check who closed the form? I don't know how to use LParam of WParam?

          J 1 Reply Last reply
          0
          • L Lost User

            Well, I tried: override protected void WndProc(ref Message m) { int message = m.Msg; if ( message == 0x0012 ) //WM_QUIT { } else if ( message == 0x0010 ) //WM_CLOSE { // Who closed the form? } base.WndProc(ref m); } but is seems that quitting windows does not raise the WM_QUIT event. It raises the WM_CLOSE event, though. But how can I check who closed the form? I don't know how to use LParam of WParam?

            J Offline
            J Offline
            James T Johnson
            wrote on last edited by
            #5

            I am truly at a loss... It appears that every single event that is raised to ask if the program/form should close just asks not providing any information as to why its asking. I've even fiddled with using reflection to get at some internal members, but all I get is "member not found" errors :(( Here's what I've found if you want to investigate it further Inside of the Application class is a nested type called ThreadContext. You can get the Type for this with this bit of code.

            public Type GetThreadContextType() {
            MemberInfo[] typesInApp = typeof(Application).FindMembers(
            MemberTypes.NestedType,
            BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public,
            new MemberFilter(memFilter), null
            );

            return MemberInfo[0].DeclaringType;
            }

            private bool memFilter(MemberInfo m, object filterCriteria)
            {
            if( m.Name.IndexOf("ThreadContext") != -1 )
            return true;
            else
            return false;
            }

            Now that class has a static method called "FromCurrent" which takes no arguments and returns the ThreadContext for the current application. This is retrieved by looking up a LocalDataStore on the Thread, the LocalDataStoreSlot is stored in a static field named tlsSlot, this slot corresponds to the thread's ThreadContext object. Once you have an instance of ThreadContext you can call the GetState method passing in the value 0x10 to see if the Thread has an AppQuit message posted or pass in 0x08 to see if the Thread has a Quit message posted. Here is the code I've been pounding out since you posted your message, if anyone can get it to work I'll buy you a beer the next time you are in the area :)

            Type app = typeof(Application);
            MemberInfo[] typesInApp = app.FindMembers(
            MemberTypes.NestedType,
            BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public,
            new MemberFilter(memFilter), null
            );

            Type typeThreadContext = typesInApp[0].DeclaringType;
            object threadContext = Thread.GetData(
            (LocalDataStoreSlot) typeThreadContext.InvokeMember(
            "tlsSlot",
            BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Static,
            null, null, new object [] { }
            )
            );

            bool StatePostedAppQuit = (bool) typeThreadContext.InvokeMember(
            "threadState",
            BindingFlags.GetField | BindingFlags.NonPublic,
            null, threadContext, new object[] { 0x10 }
            );

            bool StatePostedQuit = (bool) typeThreadContext.InvokeMember(
            "threadState",
            BindingFlags.GetField | BindingFlags.NonPublic,
            null, threadContext, new object[] { 0x08 }
            );

            L 1 Reply Last reply
            0
            • J James T Johnson

              I am truly at a loss... It appears that every single event that is raised to ask if the program/form should close just asks not providing any information as to why its asking. I've even fiddled with using reflection to get at some internal members, but all I get is "member not found" errors :(( Here's what I've found if you want to investigate it further Inside of the Application class is a nested type called ThreadContext. You can get the Type for this with this bit of code.

              public Type GetThreadContextType() {
              MemberInfo[] typesInApp = typeof(Application).FindMembers(
              MemberTypes.NestedType,
              BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public,
              new MemberFilter(memFilter), null
              );

              return MemberInfo[0].DeclaringType;
              }

              private bool memFilter(MemberInfo m, object filterCriteria)
              {
              if( m.Name.IndexOf("ThreadContext") != -1 )
              return true;
              else
              return false;
              }

              Now that class has a static method called "FromCurrent" which takes no arguments and returns the ThreadContext for the current application. This is retrieved by looking up a LocalDataStore on the Thread, the LocalDataStoreSlot is stored in a static field named tlsSlot, this slot corresponds to the thread's ThreadContext object. Once you have an instance of ThreadContext you can call the GetState method passing in the value 0x10 to see if the Thread has an AppQuit message posted or pass in 0x08 to see if the Thread has a Quit message posted. Here is the code I've been pounding out since you posted your message, if anyone can get it to work I'll buy you a beer the next time you are in the area :)

              Type app = typeof(Application);
              MemberInfo[] typesInApp = app.FindMembers(
              MemberTypes.NestedType,
              BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public,
              new MemberFilter(memFilter), null
              );

              Type typeThreadContext = typesInApp[0].DeclaringType;
              object threadContext = Thread.GetData(
              (LocalDataStoreSlot) typeThreadContext.InvokeMember(
              "tlsSlot",
              BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Static,
              null, null, new object [] { }
              )
              );

              bool StatePostedAppQuit = (bool) typeThreadContext.InvokeMember(
              "threadState",
              BindingFlags.GetField | BindingFlags.NonPublic,
              null, threadContext, new object[] { 0x10 }
              );

              bool StatePostedQuit = (bool) typeThreadContext.InvokeMember(
              "threadState",
              BindingFlags.GetField | BindingFlags.NonPublic,
              null, threadContext, new object[] { 0x08 }
              );

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              Found another (rather simple solution :laugh:), like this: protected override void WndProc(ref Message m) { const int WM_SYSCOMMAND = 0x0112; const int SC_CLOSE = 0xF060; if (m.Msg == WM_SYSCOMMAND && (int) m.WParam == SC_CLOSE) { // User clicked close button OpenDialog(false); return; } base.WndProc(ref m); } Kind regards, Ludwig

              J 1 Reply Last reply
              0
              • L Lost User

                Found another (rather simple solution :laugh:), like this: protected override void WndProc(ref Message m) { const int WM_SYSCOMMAND = 0x0112; const int SC_CLOSE = 0xF060; if (m.Msg == WM_SYSCOMMAND && (int) m.WParam == SC_CLOSE) { // User clicked close button OpenDialog(false); return; } base.WndProc(ref m); } Kind regards, Ludwig

                J Offline
                J Offline
                James T Johnson
                wrote on last edited by
                #7

                Doh! I like your version much better :) James Sonork: Hasaki "I left there in the morning with their God tucked underneath my arm their half-assed smiles and the book of rules. So I asked this God a question and by way of firm reply, He said - I'm not the kind you have to wind up on Sundays." "Wind Up" from Aqualung, Jethro Tull 1971

                L 1 Reply Last reply
                0
                • J James T Johnson

                  Doh! I like your version much better :) James Sonork: Hasaki "I left there in the morning with their God tucked underneath my arm their half-assed smiles and the book of rules. So I asked this God a question and by way of firm reply, He said - I'm not the kind you have to wind up on Sundays." "Wind Up" from Aqualung, Jethro Tull 1971

                  L Offline
                  L Offline
                  Ludwig Stuyck
                  wrote on last edited by
                  #8

                  Well, thanks anyway for the answer! Meanwhile I've joined this forum, because it's one of the best I've seen. Ludwig

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups