People are confused by ApplicationContext in Windows Forms, but there really isn't any magic happening.

Everyone knows the standard syntax Application.Run to get the message pump started and have your forms display.  What most people don't know is how the whole process works and how to get multiple forms up and running.  To get some background on you can check out this newsgroup posting where users are trying to help one another through the process, but just aren't certain about how things work http://groups.google.com/groups?selm=MPG.1a75e03c74670c38989868%40msnews.microsoft.com&oe=UTF-8.

The Application class allows you to run a message loop in three ways.  You can pass nothing, in which case the Run method will block all day long.  You can pass a Form, in which case the Form.Closed event is hooked and the application exits.  Or you can pass in an ApplicationContext.  We'll get to this last one later.  For most purposes people are going to find Application.Run(Form) to be the overload of choice.  So how can you use Application.Run(Form), but show another form?  Well, you can Show/Hide forms all day long and your thread won't exit out.  So having your main form, show sub-forms is quite easy.  What happens when your main form gets closed though?  Well, you can't let that happen using this overload.  You'll have to attach an event handler to your Closing event and return true to CancelEventArgs.Cancel.

Your other option is to just Show your first form, THEN call Application.Run with an empty constructor.  Your Form will run, but when it closes, your application won't exit.  The problem here is you won't be able to run any more code either.  So you have to be careful with this method.  You need to make sure there is a Form open at all times so you get to run code.  In the case of a wizard or a series of forms, you'd simply make sure that as one form is closing, you are opening the next form in the range.  When the last form closes you need to call Application.ExitThread and your application will shut down.

Need another option?  Application has an Idle event.  You can hook this event to make sure you can always run more code even if there aren't any active forms.  That way if the user shuts you down you can re-open your form.  You'll still need to call Application.ExitThread in order to shut the application down, but this way you have some security since you can always shut down the application from within the Idle even if you detect the lack of open forms.

Need another option?  You can throw a timer into the mix as well.  This can even be a WinForms timer, since a timer is hooked to a message pump and the Application is a message pump, you can still get timer messages even if forms aren't open.  Again, another place to load up forms if the user closes them all, or shut your application down.

Now we are ready for the ApplicationContext.  The ApplicationContext is best used for things like my wizard framework where the component itself knows how to shut things down, but the component isn't a Form.  Creating timers and hooking idle are global ways of handling things, while the ApplicationContext is more modular and object oriented.  For purposes of stringing Forms together, I would recommend that your ApplicatonContext not even bother setting the MainForm property, rather I'd make sure to hook the Closing or Closed events of all my forms to make sure that I'm always executing code.  You can still trap the Application.Idle event from within your ApplicationContext as well and use that.

Now for the kicker.  Application.Run is nothing but a blocking call to a message pump.  It is NOT the end of the world.  It is NOT the end of your application.  You can call Application.Run(Form) wait for it to exit, then call Application.Run(Form2) with the next form if your wanted.  That is yet another way to handle the whole process of displaying multiple forms and still use the default message pump.

Are there any design guidelines for this type of thing?  I don't know of any, but maybe I can get someone from the Windows Forms team to comment.  Until then enjoy playing with all of the options here that basically do the same thing ;-)

Published Sunday, April 11, 2004 4:06 AM by Justin Rogers
Filed under: ,

Comments

Tuesday, May 04, 2004 4:56 AM by Joel B.

# re: People are confused by ApplicationContext in Windows Forms, but there really isn't any magic happening.

The message pump started by Application.Run must have a mechanism for telling the OS "hey gimme just these messages -- I don't want those other ones", and a mechanism for dispatching them (i.e. code must have a way to register event handlers with the message pump).

Well, it is unclear to me how both mechanisms are implemented.
More specifically, I would like to understand how things work and why there is an Application.AddMessageFilter() method but no way to register an EventHandler

Anyone who knows, or can suggest a book that explains the mistery, could just drop me an e-mail joeblk50@microsoft.com
Thx
Joel
Tuesday, May 04, 2004 6:40 AM by Justin Rogers

# re: People are confused by ApplicationContext in Windows Forms, but there really isn't any magic happening.

You need to pull out a book on the Windows message pump. The OS really doesn't have a mechanism for saying you only want certain messages, you build that into your message pump, and pump those you don't want down to DefWndProc.

As for Dispatching, everything is based on windows handles. Controls get messages because messages are sent to the HWND. UnsafeNativeMethods.DispatchMessageW(ref msg); is responsible for this process.

As for filtering, you can always filter messages by adding a message filter on Application.AddMessageFilter. You pass it an object that implements IMessageFilter which contains the PreFilterMessage method. You can process messages here. If you want to add event based notifications, you can stack those on top of PreFilterMessage by simply returning false (that way the message is dispatched as normal), and then firing an asynchronous event massing out the Message structure.
Monday, August 16, 2004 6:37 AM by TrackBack

# No magic about ApplicationContext

Wednesday, October 28, 2009 7:36 AM by Dem

# 使用ApplicationContext类来完全封装闪屏功能

Monday, November 01, 2010 1:06 PM by الفيسبوك

# re: People are confused by ApplicationContext in Windows Forms, but there really isn't any magic happening.

and this is more confusing

Monday, May 21, 2012 8:58 PM by My notes. Заметки на полях.

# Проблемы создания Splash-screen в .Net (и не только)

Splash-screen (по-русски: экран-заставка) - это лицо вашего приложения. И чтобы не ударить в грязь лицом

# People are confused by ApplicationContext in Windows Forms, but there really isn't any magic happening. - Justin Rogers | dotnet nightmare | Scoop.it

Pingback from  People are confused by ApplicationContext in Windows Forms, but there really isn't any magic happening. - Justin Rogers | dotnet nightmare | Scoop.it

Wednesday, February 27, 2013 12:48 AM by Lyon

# re: People are confused by ApplicationContext in Windows Forms, but there really isn't any magic happening.

I love your blog.. very nice colors & theme. Did you create this website yourself or did you hire someone to do it for you?

Plz reply as I'm looking to construct my own blog and would like to find out where u got this from. cheers

Leave a Comment

(required) 
(required) 
(optional)
(required)