overriding form close button

  • Thread starter Thread starter Tom
  • Start date Start date
T

Tom

Probably a silly question, but I am having trouble
figuring out how to interrupt the close button on a
Windows form and thereby prevent the application from
actually unloading.

Any suggestions appreciated.
 
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_SYSCOMMAND = 0x112;
const int SC_CLOSE = 0xf060;


if (m.Msg == WM_SYSCOMMAND)
{
if (m.WParam.ToInt32() == SC_CLOSE)
{
return;
}
}
base.WndProc(ref m);
}
 
You can prevent a form from closing by handling its Closing event and
setting the CancelEventHandler to true.
 
You can prevent a form from closing by handling its Closing event and
setting the CancelEventHandler to true.

But what if you only want to prevent the form from closing by the X / system
menu. Wouldnt that way also prevent it from being closed in code, requiring
that youd have to kill the process through Task Manager? Or does that
Closing event only happen for the X method?

---------------------------------------
 
You're correct. When I've used this scenario I'm checking state information
in the Closing handler.

For example, if a document has not been saved, I'll prompt for a save (yes,
no, cancel). If it's yes, I save and set the handler to true. If it's no,
I skip the save and set it true. I set it to false on cancel.

You could get similar functionality by having a boolean member you test in
the handler which you set to true when you want to allow a normal exit.
 
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_SYSCOMMAND = 0x112;
const int SC_CLOSE = 0xf060;


if (m.Msg == WM_SYSCOMMAND)
{
if (m.WParam.ToInt32() == SC_CLOSE)
{
return;
}
}
base.WndProc(ref m);
}
 
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_SYSCOMMAND = 0x112;
const int SC_CLOSE = 0xf060;


if (m.Msg == WM_SYSCOMMAND)
{
if (m.WParam.ToInt32() == SC_CLOSE)
{
return;
}
}
base.WndProc(ref m);
}
 
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_SYSCOMMAND = 0x112;
const int SC_CLOSE = 0xf060;


if (m.Msg == WM_SYSCOMMAND)
{
if (m.WParam.ToInt32() == SC_CLOSE)
{
return;
}
}
base.WndProc(ref m);
}
 
Tom said:
Probably a silly question, but I am having trouble
figuring out how to interrupt the close button on a
Windows form and thereby prevent the application from
actually unloading.

\\\
Private Sub Form1_Closing( _
ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs _
) Handles MyBase.Closing
If Not ... Then
e.Cancel = True
End If
End Sub
///
 
private void closingHandler(object sender,
System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}
 
if (m.WParam.ToInt32() == SC_CLOSE)

Actually, per the docs for WM_SYSCOMMAND, you should mask out the lower 4
bits of WParam (they're "reserved for the system", whatever that means). So
to play it safe, this should be:

if ((m.WParam.ToInt32() & 0xFFF0) == SC_CLOSE)
 
Using the CancelEventArgs param worked perfectly and gave
me the results I was looking for - I knew it had to be
something simple like that...

Thanks to all who responded.

-Tom
 
I dont like the idea of "cancellable events" over catching the message
BEFORE .

If you need to catch any message and cant find out how, override the
controls WndProc and catch teh Win32 message constant and params. Always
handy to know as a workaround until u get a neater fix.
 
Back
Top