# VBForums CodeBank > CodeBank - C# >  Formless Tray Application

## jmcilhinney

VB version here.

Recently, I replied to a thread on another forum where the poster asked how to create an application that displayed an icon in the notification area (aka system tray) but didn't require a form to be created and hidden. My first thought was that a form was required but, upon reflection, I thought that there must be another way. I recalled having read something about the ApplicationContext class so I investigated that further and that is indeed the way to do it.

Generally you call Application.Run and pass a form as an argument, which becomes the application's main form. You can also pass an object whose type inherits ApplicationContext as an argument to Application.Run. The application will then close when you call Application.Exit or Application.ExitThread.

The example attached below meets the requirements of the poster of the aforementioned thread. They wanted a NotifyIcon and the ability to use an OpenFileDialog. For that, I created a component that provided a designer, which made it easy to configure the NotifyIcon and the ContextMenuStrip. My derived ApplicationContext then creates an instance of that component and duly disposes it when the ApplicationContext itself is disposed.

Simply run the app and you will see the NotifyIcon. Right-click the icon to get a menu that provides items to display an OpenFileDialog and to exit the app.

Finally, note that the attached application was written in C# 4.0, so you will need VS 2010 or C# Express 2010 to open it.

*N.B.* - The attached project was converted from the VB version using Instant C# from Tangible Software Solutions.

----------


## Nightwalker83

Cool! Saves me having to post the question later on if I need to. You mean to say you paid $300 plus dollars to convert one project from vb.net to c#?

----------


## Cavar

This is an interesting and I've been testing it out, but ran into an issue where I can't display BalloonTips for the NotifyIcon. 

The other thing I was thinking won't be possible, but I haven't tried yet, is receiving WIN32 messages like WM_HOTKEY and WM_DEVICECHANGE, which a program I am rewriting use.

These things probably won't work with this approach because they don't have a form, right?

Chris

----------


## jmcilhinney

> This is an interesting and I've been testing it out, but ran into an issue where I can't display BalloonTips for the NotifyIcon. 
> 
> The other thing I was thinking won't be possible, but I haven't tried yet, is receiving WIN32 messages like WM_HOTKEY and WM_DEVICECHANGE, which a program I am rewriting use.
> 
> These things probably won't work with this approach because they don't have a form, right?
> 
> Chris


I would have thought that balloon tips would work although I'm not sure that I've ever tested that specifically.  I'll do so when I get a chance.

This is from the documentation for the RegisterHotKey function:


> Parameters
> 
> hWnd [in, optional]
> 
>     Type: HWND
> 
>     A handle to the window that will receive WM_HOTKEY messages generated by the hot key. If this parameter is NULL, WM_HOTKEY messages are posted to the message queue of the calling thread and must be processed in the message loop.


So you can receive messages without a window, but I can't say that I have any idea how to implement a message loop in .NET.  I'd assume that you could find that info on the web somewhere but I don't know where.  It may also turn out to be more trouble than it's worth.

----------


## Cavar

> I would have thought that balloon tips would work although I'm not sure that I've ever tested that specifically.  I'll do so when I get a chance.


And you were right to think that.  :Smilie: 

I started over with your sample solution and instead of doing the "Open" logic I displayed a BalloonTip. Apparently I've mangled the version I modified extensively. lol

I'll look into the message loop when I get a chance.

Chris

----------


## jmcilhinney

I just tested and the balloon tip worked fine for me.  I changed the code to this:
csharp Code:
private void OpenMenuItem_Click(object sender, System.EventArgs e)        {            this.TrayIcon.ShowBalloonTip(2000, "The time is:", DateTime.Now.ToShortTimeString(), ToolTipIcon.Info);            //using (OpenFileDialog dialogue = new OpenFileDialog())            //{            //    if (dialogue.ShowDialog() == DialogResult.OK)            //    {            //        MessageBox.Show(dialogue.FileName);            //    }            //}        }
and selecting the Open... menu item displayed a balloon as expected.

----------


## Cavar

Ok, I'm missing something with the sample application.

I see where the menu item click events are, but I'm having trouble figuring our where to put my startup code, such as fetching data, adding more menu items, showing balloontips, etc.

I tried adding an empty contructor in the TrayApplicationManager class, but VS said it already had one with those parameters types.

I found another application that uses ApplicationContext on CodeProject and I just put my startup code in the ApplicationContext directly. I would have thought it would be the same with your sample.

I know I must be missing something really simple and I'll look like an idiot when you explain, but I'll risk it.  :Smilie: 

Any thoughts or input?

Chris

----------


## Cavar

I don't know if it was the right thing to do, but I just moved the following code from the *TrayApplicationManager.Designer.cs* file to the *TrayApplicationManager.cs* file.



```
public TrayApplicationManager() : base()
{
	//This call is required by the Component Designer.
	InitializeComponent();
}
```

I think my main issue was the fact that I would have had to put all my code in the *TrayApplicationManager.Designer.cs* file with all of that pre-generated coed and I didn't really want to do that.

I'm still open to other suggestions though.

Chris

----------


## jmcilhinney

The reason that I added the TrayApplicationManager was so that I would have a design surface to add components to, so that I wouldn't have to create them in code.  You could certainly do it all in the custom ApplicationContext if you wanted to.  You could also put initialisation code in the Main method.

----------


## Cavar

I found some code for a HotKeyManager class (link) and have integrated it with your demo application.

I added 2 HotKeys for testing. CTRL+SHIFT+A and CTRL+SHIFT+W.

Hope it's ok to attach it to this this thread. If not, maybe the Mods can delete my post and I'll move it to a new thread.

Thanks,
C

----------


## jmcilhinney

> I found some code for a HotKeyManager class (link) and have integrated it with your demo application.
> 
> I added 2 HotKeys for testing. CTRL+SHIFT+A and CTRL+SHIFT+W.
> 
> Hope it's ok to attach it to this this thread. If not, maybe the Mods can delete my post and I'll move it to a new thread.
> 
> Thanks,
> C


That's fine and actually quite helpful, so thanks.  Just one point to note: attaching binary files is not allowed and, from the size of your ZIP file, I'm guessing that it contains binaries.  If that's the case, can you please remove it and add a new one that doesn't.  To that end, you must always delete the bin and obj folders from every project before zipping them up for attachment.

----------


## Cavar

> That's fine and actually quite helpful, so thanks.  Just one point to note: attaching binary files is not allowed and, from the size of your ZIP file, I'm guessing that it contains binaries.  If that's the case, can you please remove it and add a new one that doesn't.  To that end, you must always delete the bin and obj folders from every project before zipping them up for attachment.


Yeah, I have an empty bin folder and the obj folder has a 7kb cache file in it. I'll delete them both and reattach, just to be safe.

UPDATE: Well, I deleted the obj and bin folders and and didn't shrink much. I think it's just all the extra code in the HotKeyManager class causing the size increase.

C

----------

