How to start WinForm app minimized to tray?

53,958

Solution 1

The right way to do this is to prevent the form from getting visible in the first place. That requires overriding SetVisibleCore(). Let's assume a context menu for the NotifyIcon with a Show and Exit command. You can implement it like this:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        notifyIcon1.ContextMenuStrip = contextMenuStrip1;
        this.showToolStripMenuItem.Click += showToolStripMenuItem_Click;
        this.exitToolStripMenuItem.Click += exitToolStripMenuItem_Click;
    }

    private bool allowVisible;     // ContextMenu's Show command used
    private bool allowClose;       // ContextMenu's Exit command used

    protected override void SetVisibleCore(bool value) {
        if (!allowVisible) {
            value = false;
            if (!this.IsHandleCreated) CreateHandle();
        }
        base.SetVisibleCore(value);
    }

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (!allowClose) {
            this.Hide();
            e.Cancel = true;
        }
        base.OnFormClosing(e);
    }

    private void showToolStripMenuItem_Click(object sender, EventArgs e) {
        allowVisible = true;
        Show();
    }

    private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
        allowClose = true;
        Application.Exit();
    }
}

Note a wrinkle with the Load event, it won't fire until the main form is first shown. So be sure to do initialization in the form's constructor, not the Load event handler.

Solution 2

I'm reading all the answers and see hacks and black magic... (no offense, mates)

No hacks needed. You don't even have to set "ShowInTaskbar=false" and other stuff. Just do this:

    //"Form Shown" event handler
    private void Form_Shown(object sender, EventArgs e)
    {
        //to minimize window
        this.WindowState = FormWindowState.Minimized;

        //to hide from taskbar
        this.Hide();
    }

NOTE: I strongly recommend NOT TOUCHING the "ShowInTaskbar" property. For example, if your application registers system-wide hotkeys or other similar stuff (hooks, etc) - setting ShowInTaskBar=false and minimizing your app will prevent Windows from sending some messages to your window... And your hooks/hotkeys/etc will stop working.

Solution 3

In the constructor, remove these two lines:

this.Visible = false;
this.ShowInTaskbar = false;

and add after InitializeComponent();:

this.WindowState = FormWindowState.Minimized;

In designer, set ShowInTaskbar to false & FormWindowState to Normal.

EDIT: If you post the same in Load event, the window does get minimized but still shows minimized on the desktop. I think this is a bug.

Solution 4

When minimizing an application and you want to hide it from Alt+Tab:

You also need to set the Opacity to stop the titlebar showing near the Start Menu when you set the Border Style to a Tool Window.

On Minimize Event:

this.Visible = false;
this.Opacity = 0;
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
this.ShowInTaskbar = false;

On Normalize Event:

this.Visible = true;
this.Opacity = 100;
this.FormBorderStyle = FormBorderStyle.FixedSingle; //or whatever it was previously set to
this.ShowInTaskbar = true;
Share:
53,958
jluce50
Author by

jluce50

Updated on June 30, 2021

Comments

  • jluce50
    jluce50 almost 3 years

    I've successfully created an app that minimizes to the tray using a NotifyIcon. When the form is manually closed it is successfully hidden from the desktop, taskbar, and alt-tab. The problem occurs when trying to start with the app minimized. At first the problem was that the app would be minimized but would still appear in the alt-tab dialog. Changing the FormBorderStyle to one of the ToolWindow options (from the "None" option) fixed this, but introduced another problem. When the app first starts the titlebar of the minimized window is visible just above the start menu:

    enter image description here

    Opening the form and the closing it causes it to hide properly. I've tried lots of variations, but here's essentially how it's working right now...

    WindowState is set to Minimized in the Designer. After some initialization in the constructor I have the following lines:

    this.Visible = false;
    this.ShowInTaskbar = false;
    

    When the NotifyIcon is double-clicked I have the following:

     this.WindowState = FormWindowState.Normal;
     this.Visible = true;
     this.ShowInTaskbar = true;
    

    Like I said, I've tried lots of minor variations on this (this.Hide(), etc.). Is there a way to have the NotifyIcon be the primary component such that I can completely start and dispose of the form while leaving the NotifyIcon running? There's got to be a way to start the app with the form minimized without any of the weirdness. Please help me find it!

  • Joel Coehoorn
    Joel Coehoorn over 14 years
    Or in the form's load event, since the constructor is designer-generated and you're apt to have your change disappear on you now and then.
  • Miles
    Miles over 14 years
    I agree, load event would be a better place
  • Yogesh
    Yogesh over 14 years
    See my edit. Your change will disappear only if you post the line I have posted before InitializeComponent();. All your designer settings are loaded in InitializeComponent();.
  • jluce50
    jluce50 over 14 years
    Okay, I moved the initialization code to the load event and made the suggested change. No dice. I still get the minimized title bar on the desktop, only now it doesn't disappear even after manually closing the form. Any other ideas?
  • jluce50
    jluce50 over 14 years
    Re: EDIT: It does seem like bug, but there have got to be people out there doing what I'm trying to do. I'd think a bug like this would be getting a lot more attention...
  • Yogesh
    Yogesh over 14 years
    Let it remain in the constructor only!! Read my answer again.
  • Philip Wallace
    Philip Wallace over 14 years
    @Joel - only InitializeComponent is designer-generated... not the entire constructor!
  • jluce50
    jluce50 over 14 years
    @Yogesh: I did exactly as you described and still have the same problem. As I mentioned in the OP, I can resolve it by changing the FormBorderStyle to something other than ToolWindow, but then I have the problem of it appearing in the alt-tab dialog even when minimized.
  • jluce50
    jluce50 over 14 years
    Brilliant, thanks! Took a little tweaking to get it to work with my specific app, but it works great!
  • psulek
    psulek over 12 years
    Small change in exit click handler, to not show form when exiting application from context menu when form was not showed, replace line if (!mLoadFired) Show(); with code: if (mLoadFired) Close(); else Application.Exit();
  • 7heo.tk
    7heo.tk over 10 years
    This solution achieves the same result as the most-voted and chosen one; while it doesn't do any (therefore unnecessary) overly complicated hacking... As a result, it should be first. Meh...
  • Brad
    Brad about 8 years
    I was doing research on how to do this for my program and this answer was the most simple and effective way to accomplish my goal.
  • tanascius
    tanascius almost 7 years
    The line if (!this.IsHandleCreated) CreateHandle(); is of great value ... it prevents ThreadExceptions later. Thanks for the answer!
  • LarsTech
    LarsTech over 6 years
    What language is that?
  • user2404597
    user2404597 about 6 years
    @Brad no, you still need to add a NotifyIcon manually. but it will do the trick after you have the icon added.
  • heXer
    heXer about 5 years
    I had everything in place for minimizing to tray (notification area) and it worked when triggered manually. This was the only thing missing to have it automatically on start. No hacking involved. Great answer!
  • user1062142
    user1062142 almost 5 years
    Works perfectly- amazing that it took me about 2 hours of googling and testing other methods to get this. Thanks so much.
  • user1062142
    user1062142 almost 5 years
    And FYI- for newer users of VS - in the form properties of the UI Designer, look for the "SHOWN" event - not "FORM SHOWN".