Writing a pure SysTray Application without a Window

One nice day I had to implement a pure SysTray application. The application should stay in SysTray with a notification icon, but without a main window. So my first thought was to hide the application window within the OnLoad(). At this point my adventure started.

I really fast came to the conclusion that it's not possible to hide a main window by setting the visibility to false. So what to do. I was searching with google and found some hints like set the window size to 1,1 or opacity to 0% and so on. The best idea was to call a native Windows API which hides the window. Cruel … All this solutions operated as a workaround but did not solve the problem.

So I did some research and found a solution which works without having such cruel workarounds.

The idea is not to create a window and to hide it. You create your own application context which simply consists of a notification icon without a window. So you don't have to hide it, because it's not existend.

///
/// New Context class derived from the application context
///
public class SysTrayContext: ApplicationContext
{
    private SysTrayNotification notification;

    #region STA Thread

    ///
    /// Start Thread and run the new sys tray context
    ///
    [STAThread]
    private static void Main()
    {
        Application.Run(new SysTrayContext());
    }

    #endregion

    ///
    /// Initializes a new instance of the class.
    ///
    public SysTrayContext()
    {
        notification = new SysTrayNotification();
        notification.Visible = true;
    }
}

The SysTrayNotification class does only contain a simple NotificationIcon and a ContextMenu. So it's easy to implement.

///
/// Initializes a new instance of the class.
///
public SysTrayNotification ()
{
    /*
     * Set the systray icon
     */
    Assembly thisExe = Assembly.GetExecutingAssembly();
    Stream iconStream = thisExe.GetManifestResourceStream(NTSVC);
    notifyIcon.Icon = new System.Drawing.Icon(iconStream);

    /*
     * Create the context menu
     */
    menu.MenuItems.Add("&Say hello world", new EventHandler(SayHello) );
    menu.MenuItems.Add("-");
    menu.MenuItems.Add("&Close", new EventHandler(OnClose));

    notifyIcon.ContextMenu = menu;
}

As you can see you don’t have to care for hiding the main application window – because you don’t have any.

The whole example can be downloaded from:
Writing a pure SysTray Application without a window.