0

I'm trying to make my application minimize to system tray when I close the form.

I want it to minimize to tray when the Close button (red 'X') is clicked and preferably when the window is right clicked and 'Close' selected on the task bar.

However I want other forms of closing to remain intact. I.E. 'Alt-F4' and coded 'Form.Close()'

I tried looking for a solution and found that there is a 'FormClosingEvent.CloseReason' which contains 'CloseReason.UserClosing'

This is flagged when I click the Close button, but unfortunately it is also flagged when I use 'Alt-F4' and seemingly when the code uses 'Form.Close()'

I found several ways of intercepting 'Alt-F4', these are of no use to me, I wish 'Alt-F4' remain intact.

To clarify I wish to intercept ONLY: 'Close' button (red 'X') being clicked and the right-click close on the task bar.

Think of it like this:

1. The user clicks the red 'x'
2. The red 'x' calls a method/event
3. The method/event calls Form.Close()

I want to intercept before it reaches Form.Close(), preferably before 2 happens. Is there any way to do this?

I don't know all of the ways of closing the form and or application. Of those I know:

  • Task Manager: Intact.
  • Alt-F4: Intact.
  • Shut Down: Intact.
  • Red 'X' Close Button: Intercepted.
  • Right-click task bar select 'Close': Intercepted.

I hope that helps.

Thank you for any help you can give.

Zynthia Zenithene

  • There is this [answer](http://stackoverflow.com/questions/2643712/c-sharp-disable-altf4-but-allow-the-the-form-to-be-closed-by-code-closereason), which seems to explain how to do what you want to do, if you reverse the effects of the cancel, of course. – Calliah Sep 10 '14 at 23:19
  • @Calliah This only shows me how to intercept the 'Alt-F4', I'm trying to intercept the 'Close' button. Thanks for trying though. – Zynthia Zenithene Sep 10 '14 at 23:24
  • I think you misunderstand. The link I posted is a variation of what Nathan A is suggesting. As I mentioned, if you were reverse the conditions of the cancel in the link's first answer, it would provide you with what you are looking for. – Calliah Sep 10 '14 at 23:26
  • @ZynthiaZenithene - You could always set the [FormBorderStyle](http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formborderstyle(v=vs.110).aspx) to None, then create your own close button that does anything you want. [This Article](http://www.codeproject.com/Articles/42223/Easy-Customize-Title-Bar) describes one way to do that. – Icemanind Sep 10 '14 at 23:35
  • @ Calliah Ok, I understand what your saying, it's just that I don't want to intercept 'everything else' I.E. the 'Alt-F4' without knowing what everything else entails. What if something else flagged 'CloseReason = CloseReason.UserClosing'. How would I ensure that was flagged also? – Zynthia Zenithene Sep 10 '14 at 23:36
  • 4
    You forgot to be specific and didn't mention what is supposed to happen with the 4 other ways to close the window: using the Close menu item in the system menu, the Close item in the context menu of the taskbar button, the close glyph in the Aero thumbnail, the Close option in Task Manager. It is certainly best to **not** give the user so many ways to get utterly confused about how to do it your way. – Hans Passant Sep 10 '14 at 23:38
  • @icemanind That sounds like an interesting idea, although I already use 'FormBorderStyle = None' for full screen purposes. I can just hide and show it within the code though. If nothing else comes up I might use that instead. – Zynthia Zenithene Sep 10 '14 at 23:41
  • 2
    Alt+F4 is supposed to do the same thing as clicking the X - close the form. Whether that closes your app or not is another question. I would be confused and annoyed if your app minimized to tray only when I clicked and not when I pressed alt+f4. – Blorgbeard Sep 11 '14 at 00:07
  • @Blorgbeard I prefer it the other way, 'Alt-F4' is my instinct when trying to exit something. if it's not working or if it's taking up too many resources etc. My second instinct is task manager and end process. Although things that take up that much, that I need to close them, make opening task manager difficult and slow, if not impossible at times. Of all the people I know if something is not working press 'Alt-F4'. It annoys me when programs make it difficult to exit. My minimizing to tray will become a preference option. Most exit methods should stay intact. – Zynthia Zenithene Sep 11 '14 at 00:15
  • @ZynthiaZenithene it's fine for it to be a preference, but for me, if "Minimize to tray" was on, I would expect Alt+F4 to do that, not exit. – Blorgbeard Sep 11 '14 at 00:19
  • @Blorgbeard Thanks for your opinion. I'll add it as a preference as well. Managing 'Alt-F4' is much easier than this 'Close' button is. – Zynthia Zenithene Sep 11 '14 at 00:22

3 Answers3

2

I'd suggest using a flag (bool _allowClose;, for example). You stated that you can already intercept Alt-F4, and I'm assuming that happens before the Closing event occurs.

During the Alt-F4 intercept, set _allowClose = true and then during the closing event, allow the Close to occur only if _allowClose == true. It may not be the cleanest method, but it's worked for me in the past.

For example:

public class MyForm : Form 
{
    bool _allowClose = false;

    void Form_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Alt && e.KeyCode == Keys.F4) _allowClose = true;
    }

    void Form_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (!_allowClose && e.CloseReason == CloseReason.UserClosing)
        {
            e.Cancel = true;
            WindowState = FormWindowState.Minimized;
        }
    }
}
Nathan A
  • 11,059
  • 4
  • 47
  • 63
  • This is the only way I've thought of so far, but I'm really looking for a way to not intercept the 'Alt-F4'. I would like to change the specific events of the 'Close' button and maybe also the taskbar's 'Close' button. – Zynthia Zenithene Sep 10 '14 at 23:26
0

try this, but I dont have function keys on my keyboard to test the ALT+F4 event.

    protected override void WndProc(ref Message m)
    {
        int WM_SYSCOMMAND = 0x0112;
        int SC_CLOSE = 0xF060;

        if (m.Msg == WM_SYSCOMMAND && m.WParam == new IntPtr(SC_CLOSE))
        {
            WindowState = FormWindowState.Minimized;
            return;
        }

        base.WndProc(ref m);
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys.Alt | Keys.F4))
        {
            this.Close();
            return true;
        }

        return base.ProcessCmdKey(ref msg, keyData);
    }
  • Thanks for the idea, unfortunately it affects 'Alt-F4' as well, giving me the same result as if I had checked for 'CloseReason.UserClosing' – Zynthia Zenithene Sep 10 '14 at 23:51
  • The Close System menu item has ALT+F4 shortcut key assigned to it so when when ALT+F4 was pressed SC_CLOSE was passed. But the above change should trap the ALT+F4. – dharshana jagoda Sep 11 '14 at 01:38
0

This simple method is working..

Place a NotifyIcon control to your form

Apply an icon file to your form Icon Property

this.Closing event might not appear in prediction / Intelli sense so write it down, it will work..

public Form1()
    {
        InitializeComponent();
        this.Closing += Form1_Closing;
        notifyIcon1.Icon = this.Icon;
        notifyIcon1.Click += notifyIcon1_Click;
    }


void Form1_Closing(object sender, CancelEventArgs e)
    {
        e.Cancel = true;
        notifyIcon1.Visible = true;
        Hide();
    }

 void notifyIcon1_Click(object sender, EventArgs e)
    {
        Show();
        notifyIcon1.Visible = false;
    }

You can also add a balloon tip like your application is running in notification tray..

Abdul Saleem
  • 10,098
  • 5
  • 45
  • 45