<

Go Premium for a chance to win a PS4. Enter to Win

x

Building a Formless WinForms Application with a NotifyIcon in VB.Net 2008

Published on
36,703 Points
22,403 Views
13 Endorsements
Last Modified:
Awarded
This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray.

The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Run() instead of a Form instance.  With this approach we automatically get a built-in message pump and do not see any ugly Console windows.  Having a message pump means that an infinite loop is not necessary to keep the app "alive".  It also means that we can freely create Controls and Forms at run-time and respond to their events as usual.  We can even elegantly multi-thread the application by using a BackgroundWorker() Control from within the Inherited ApplicationContext Class.

Why would you want to do this?  Perhaps you have a "background" operation that needs to run all the time and would like to give the user a way to interact with the application.  The tray icon gives you the option to display menus or simply popup a configuration dialog if clicked.  This is an easy approach compared to implementing a full blown service.

The ApplicationContext provides complete freedom in controlling when the program is closed.  You are no longer constrained to just the two shutdown mode choices of "When startup form closes" or "When last form closes".  With no "startup form" you can now freely switch between forms without worrying about the app closing on you.  You can display a Login form and then actually completely close it before moving on to the Main form.  No more need to show the Main form with ShowDialog() or keep the Login form hidden just to keep the app alive!  Shared variables in the ApplicationContext class can be used to store information that the entire program needs access to (such as privilege levels).  Since the app only shuts down when you explicitly call Application.Exit() you can build a program that only closes when the conditions are right for your particular scenario.

Note that this technique can also be used without any GUI elements at all!  The app will happily run without any interface and will still have a message pump making it easier to work with than a Console app.

Let's get started:

1. Project Type

Start with a standard WinForms ApplicationStart with a standard WinForms Project

2. Project Properties

Click on Project --> PropertiesClick on Project --> Properties

3. Change the Entry Point

Disable the Application Framework and set the "Startup Object"Disable the Application Framework and Change the "Startup Object"

4. Add Tray Icon

Switch to the Resources Tab and add your Icon File (.ico)Add the Icon for you NotifyIcon to the Resources Tab

5. Embed the Icon

Change the Persistence Mode of the Icon to EmbeddedChange the Persistence Mode of the Icon

6. Add Module

Add a Module to the Project.  Leave the default name, Module1Add a Module to the Project

7. ([b]Optional[/b]) Remove Form1

Delete the default Form if you don't need it
(Forms can still be used in the application if you desire!)Optionally Delete the default Form if you don't need it

8. Add Code

Replace the code in the Module with the listing below.
Important! Change "My.Resources.Happy" in line #17 so that it correctly reflects the name of your Embedded Icon
Module Module1

    Public Sub Main()
        Application.Run(New MyContext)
    End Sub

End Module

Public Class MyContext
    Inherits ApplicationContext

    Private WithEvents TrayIcon As New NotifyIcon
    Private WithEvents CMS As New ContextMenuStrip
    Private WithEvents ExitMenu As New ToolStripMenuItem("Exit")

    Public Sub New()
        TrayIcon.Icon = My.Resources.Happy
        TrayIcon.Text = "ApplicationContext with a NotifyIcon" ' <-- Tooltip on the NotifyIcon
        TrayIcon.Visible = True

        CMS.Items.Add(ExitMenu)
        TrayIcon.ContextMenuStrip = CMS

        ' You can add a BackgroundWorker control to the class and start a lengthy process from here...
    End Sub

    Private Sub CMS_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles CMS.Opening
        ' From this event you can control which menu items appear (visibility or disabled) or 
        ' even cancel the event and prevent the context menu from appearing at all
    End Sub

    Private Sub ExitMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ExitMenu.Click
        Application.Exit()
    End Sub

    Private Sub MyContext_ThreadExit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ThreadExit
        TrayIcon.Visible = False
    End Sub

End Class

Open in new window


9. Test it out!

Run the Project
Hopefully you'll get an Icon in the System Tray that has an "Exit" option when you Right Click it

In the images below, the Happy face is the icon being displayed by the application:The NotifyIcon in the System Tray displaying its ToolTipThe NotifyIcon in the System Tray displaying its ContextMenuStrip
13
Comment
10 Comments
 
LVL 49

Expert Comment

by:DanRollins
Excellent article!  You made it sound so easy (and showed that it is :-)
You got my Yes vote!
0
 
LVL 96

Expert Comment

by:Bob Learned
Mike, sometimes, I wonder just how idle your mind really  is!! *WINK*  There is something subtle, yet powerful, in this article about the ApplicationContext, which is the glue that pulls all the pieces together in one simple line:

     Application.Run(New MyContext)

Thanks!!

Bob
0
 
LVL 2

Expert Comment

by:Vishnukumar
This article rocking.. This is what i need for my application.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 38

Expert Comment

by:PaulHews
Great article and very useful!  
0
 
LVL 48

Expert Comment

by:jpaulino
Great article Idle_Mind!
0
 

Expert Comment

by:RIAS
Thanks for the article.One of the best article I ever read.
As always brilliant and truly Genius IDLE_MIND.

0
 

Expert Comment

by:pxj05
X E Lent. Works in VS 2005 as well.
0
 
LVL 19

Expert Comment

by:Shahan Ayyub

Idle_Mind great Article. Thanks for sharing it.
I think the rumor is not rumor it is reality. ;)  just kidding
0
 
LVL 15

Expert Comment

by:JackOfPH
Thanks, very useful.

Great Article...
0
 

Expert Comment

by:IssacJones
Hi guys

Thanks for all your comments unfortuntately all seem to have a problem in that if "Enable application framework" is unchecked then the Splash Screen I have added is not called and displayed.

Any ideas?

Issac
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Join & Write a Comment

We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month