In this article, you will get a walkthrough of creating an Application Event Handler Component (AEHC) for any WinForms application in .NET. AEH is an event handler for your WinForms application. The primary functionality of this component is to raise an event after every form loads into memory so that we can handle its event for performing any custom code processing and return the control to the form after processing.
Let’s consider a scenario. While implementing security into our application, we may have to disable or enable certain controls on every form according to the role of the user accessing the form. For this, we will call a custom method [for instance,
AuthorizeMe()] to perform custom authentication and authorization from each and every form in our application. Suppose, if in any case, we forget to call its method from one of our forms, in result, there will be no security applied to that form.
Now, with AEHC, we only call the method
AuthorizeMe() once per application from AEHC, and then it's AEHC’s responsibility to execute
AuthorizeMe() every time after the form is loaded.
What is Application Event Handler Component?
In ASP.NET, we can create custom HTTP Modules for adding custom processing to each and every web page in web applications at a global level. One of the benefits you get using a HTTP Module is that you do not need to call them from each and every web page; they will automatically get executed for each of them. In Application Event Handler, you will achieve a similar functionality of HTTP Modules. However, AEHC will be specific to every application in contrast with HTTP Modules which can be used machine wide.
Application Event Handler Component keeps track of the forms being loaded and unloaded throughout the application’s lifecycle and generates events like
FormUnloaded() at application level. Just like HTTP Modules, you too can write your own modules to manipulate the forms properties in these events (see Figure 1).
Figure 1 Application Event Handler Component Lifecycle
Dim WithEvents myHandler As New AEHC.ApplicationEventHandler
Public frCol As ArrayList
Public Sub main()
Private Sub myHandler_FormLoaded(ByRef sender As System.Windows.Forms.Form, _
ByVal e As AEHC.AppEventHandlerArgs) Handles myHandler.FormLoaded
sender.Text = Now.ToLocalTime
Private Sub myHandler_FormUnloaded(ByVal e As AEHC.AppEventHandlerArgs) _
MsgBox(e.FormsCollection.Count & " in memory")
Architecture of Application Event Handler Component
Application Event Handler component is built upon window messages released by WinForms. The core part of AEHC is a
FormFilter, which is a custom message filter class created by implementing
Let’s get into the details and see how Application Event Handler component works (see Figure 2). When you load a WinForms application, it generates messages for most of its events. You can filter the message queue by using a custom message filter.
Let’s create a Forms Collection to hold all the forms which are being loaded throughout the application. Get the Active Form in the application. Check if the form exists in the Forms Collection, add the Form in the collection if not.
Now add a handler to
Closed event, which you will use to remove the form from the collection when the form receives its
Close event. Now, raise the
FormLoaded() for passing the control to the user. User can handle the event and perform some custom processing like custom authentication, adding new controls in the loaded form changing the form’s appearance.
Figure 2 Workflow of Application Event Handler Component
Creating an Application Event Handler Component
Application Event Handler is composed of two classes:
FormMessageFilter Class: This class is responsible for filtering messages being dispatched by a form or control. It implements an
IMessageFilter to design a custom message filter (
IMessageFilter interface is used to capture a message before it gets dispatched to a form or control).
Declare two events
FormUnload() and an
ArrayList to store the Forms collection.
PreFilterMessage method of
IMessageFilter, check the
Msg property of the message with message codes (see Table 1) and trap the events. Return
False to dispatch the message and vice versa.
MSG property to
&HF for filtering the window paint messages. Look for the
Form.ActiveForm property to identify the form and add the
Form to the Forms Collection. Attach an event handler to form, for removing it from the collection after it is closed.
|0x000F||Sent when the system or another application makes a request to paint a portion of an application's window|
|0x0100||Posted to the window with the keyboard focus when a non system key is pressed|
|0x0101||Posted to the window with the keyboard focus when a non system key is released|
|0x0200||Posted to a window when the cursor moves|
|0x0201||Posted when the user presses the left mouse button while the cursor is in the client area of a window|
|0x0202||Posted when the user releases the left mouse button while the cursor is in the client area of a window|
|0x0203||Posted when the user double-clicks the left mouse button while the cursor is in the client area of a window|
|0x0204||Posted when the user presses the right mouse button while the cursor is in the client area of a window|
|0x0205||Posted when the user releases the left mouse button while the cursor is in the client area of a window|
|0x0206||Posted when the user double-clicks the right mouse button while the cursor is in the client area of a window|
|Note: See WINUSER.H for more message codes|
Table 1: Message Codes for using in the Custom Filter Class
Friend Shared frmCollection As New ArrayList
Public Event FormFound(ByRef sender As Form)
Public Event FormUnload()
Public Function PreFilterMessage(ByRef m As _
System.Windows.Forms.Message) As Boolean Implements _
If (m.Msg = &H200) Then
If Not (Form.ActiveForm) Is Nothing Then
Dim curForm As Form = Form.ActiveForm
If Not (Search(curForm, frmCollection)) Then
AddHandler curForm.Closed, AddressOf MyForm_Closed
Private Sub MyForm_Closed(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim k, j As Integer
For i As Integer = 0 To frmCollection.Count - 1
j = i - k
If j > (frmCollection.Count - 1) Then Exit For
If frmCollection(j).IsDisposed = True Then
k = k + 1
If Not (sender) Is Nothing Then frmCollection.Remove(sender)
Private Function Search(ByVal fr As Form, _
ByVal frmArray As ArrayList) As Boolean
Dim fr1 As Form
For Each fr1 In frmArray
If fr.Equals(fr1) Then Return True
- Application Event Handler: adds the
FormMessageFilter to the application's message pump to filter out the form paint messages. And a shared read only
FormsCollection property to access the collection of forms at runtime.
Public Class ApplicationEventHandler
Public Event FormLoaded(ByRef sender As Form)
Public Event FormUnloaded()
Public Shared ReadOnly Property FormsCollection() As ArrayList
Public Sub Init()
Dim MyFilter As New FormMessageFilter
AddHandler MyFilter.FormFound, AddressOf pFormLoaded
AddHandler MyFilter.FormUnload, AddressOf pFormUnLoaded
Private Sub pFormLoaded(ByRef CurForm As Form)
Private Sub pFormUnLoaded()
You have successfully created the Application Event Handler component.
Using Application Event Handler Component
Now all said and done, you have finished creating the Application Event Handler Component. Let’s learn to use the same, in your WinForms project.
Create a new WinForms application in VB.NET. To use AEHC with VB.NET WinForms application, you will need to add a module and code a
Sub main method.
Add a reference to AEHC, and instantiate in the module using
WithEvents, when you want to trap the
Initialize the instance by calling
Init() will register AEHC for the application and starts monitoring the message queue.
FormLoaded() event, add code for adding a
Label control to the loaded form, and for
FormUnloaded() event, just add a message box and use the
FormsCollection property of the AEHC to get the number of loaded forms by
Dim WithEvents myHandler As New AEHC.ApplicationEventHandler
Public Sub main()
‘Initialize the component
Private Sub myHandler_FormLoaded(ByRef sender As _
System.Windows.Forms.Form) Handles myHandler.FormLoaded
Dim label1 As System.Windows.Forms.Label
label1 = New System.Windows.Forms.Label
label1.Font = New System.Drawing.Font("Arial", 14.25!, _
System.Drawing.GraphicsUnit.Point, CType(0, Byte))
label1.Location = New System.Drawing.Point(8, 8)
label1.Name = "Label1"
label1.Size = New System.Drawing.Size(208, 23)
label1.TabIndex = 0
label1.Text = " Application Event Handler Component Magic "
Private Sub myHandler_FormUnloaded() Handles myHandler.FormUnloaded
Run your project to see the magic of your Application Event Handler Component. You will see a label with text “Application Event Handler Component Magic” on your form. To do more testing, you can also place a button on the form and create new instances of the form; you will get amazing functionality like all the forms being displayed with the label control.
Application Event Handler Component is remarkably very powerful for WinForms developers, which they can extensively use in UI Customization of WinForms, along with other tasks. They can make use of the
FormCollection property too, for manipulating forms in their application.
Message Filters are one of the easiest ways to add custom processing for each Form in your WinForms application. In fact, you can imitate some more good features of ASP.NET in your WinForms apps by using the same mechanism. In future columns, I'll explore more on implementing ASP.NET's features in WinForms, like Caching, etc.