Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>.NET Reflector is your friend when working out how WinForms is operating.</p> <p>The Form class has an internal field called <em>closeReason</em> and this is used when generating the event parameter that you examine in the <em>Closing</em> event. This internal field is set in four different places that I can find. These are...</p> <p>1, <strong>The Form.Close() method sets the closeReason = UserClosing.</strong> </p> <p>This makes sense as making a manual call to the <em>Form.Close()</em> method is usually the result of some user action, such as a <em>File->Exit</em> menu option being selected by the user. Clearly this is a user action.</p> <p>2, <strong>The WM_SYSCOMMAND (SC_CLOSE) sets the closeReason = UserClosing.</strong></p> <p>The <em>WndProc</em> of the <em>Form</em> processes the <em>SC_CLOSE</em> system command by setting the <em>closeReason</em> to <em>UserClosing</em> and the lets the default window proc execute and close the application. This makes sense as this <em>SC_CLOSE</em> is sent when the user presses the window close chrome button or selected the close option from right clicking the title bar. Both are user actions and so setting the <em>closeReason</em> to <em>UserClosing</em> appears correct.</p> <p>3, <strong>WndProc processes message <code>WM_CLOSE</code> (0x10) with closeReadon = TaskManagerClosing</strong></p> <p><code>WM_CLOSE</code> is sent by task manager and other applications to close a window and if the <em>closeReason</em> is currently equal to <em>None</em> it updates it to <em>TaskManagerClosing</em>. Note this issue with it being updated only if it is <em>None</em> as I think this is a problem for you.</p> <p>4, <strong>WndProc processes messages 0x11 and 0x16 with closeReason = WindowsShutDown</strong></p> <p>This is not very interesting as you do not care about this scenario but it is just standard processing of shut down messages.</p> <p>So the core problem you are having is that at no point is the <em>closeReason</em> being reset back to <em>None</em> when you cancel the <em>Closing</em> event. Therefore point number 3 above will never correctly update the value to <em>TaskManagerClosing</em> if that occurs after your cancel. As the closeReasson is an internal field you cannot update it directly. But you can cheat and this is an approach I have used myself in the past. You need to use reflection to get access to the internal field and then reset it to <em>None</em> when you set <em>Cancel=true</em> in your event handler.</p> <p>I have not tested this code but you need something along the lines of...</p> <pre><code>PropertyInfo pi = typeof(Form).GetProperty("CloseReason", BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.NonPublic); pi.SetValue(this, CloseReason.None, null); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload