![]() |
Languages »
VB.NET »
Windows Forms
Intermediate
Application Event Handler for WinFormsBy SaurabhdotnetIn this article, you will get a walkthrough of creating an Application Event Handler Component (AEHC) for any WinForms application in .NET. |
VB, Windows, .NET 1.0, .NET 1.1, WinForms, VS.NET2003, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

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.
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 FormLoaded() and 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()
'Attaches the Form Filter to the Application
myHandler.Init()
Application.Run(New Form1)
End Sub
Private Sub myHandler_FormLoaded(ByRef sender As System.Windows.Forms.Form, _
ByVal e As AEHC.AppEventHandlerArgs) Handles myHandler.FormLoaded
sender.Text = Now.ToLocalTime
End Sub
Private Sub myHandler_FormUnloaded(ByVal e As AEHC.AppEventHandlerArgs) _
Handles myHandler.FormUnloaded
MsgBox(e.FormsCollection.Count & " in memory")
End Sub
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 IMessageFilter.
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 Form 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
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 FormFound(), FormUnload() and an ArrayList to store the Forms collection.
In 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.
Compare the 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.
| Message | Code | Purpose |
|---|---|---|
WM_PAINT |
0x000F | Sent when the system or another application makes a request to paint a portion of an application's window |
WM_KEYDOWN |
0x0100 | Posted to the window with the keyboard focus when a non system key is pressed |
WM_KEYUP |
0x0101 | Posted to the window with the keyboard focus when a non system key is released |
WM_MOUSEMOVE |
0x0200 | Posted to a window when the cursor moves |
WM_LBUTTONDOWN |
0x0201 | Posted when the user presses the left mouse button while the cursor is in the client area of a window |
WM_LBUTTONUP |
0x0202 | Posted when the user releases the left mouse button while the cursor is in the client area of a window |
WM_LBUTTONDBLCLK |
0x0203 | Posted when the user double-clicks the left mouse button while the cursor is in the client area of a window |
WM_RBUTTONDOWN |
0x0204 | Posted when the user presses the right mouse button while the cursor is in the client area of a window |
WM_RBUTTONUP |
0x0205 | Posted when the user releases the left mouse button while the cursor is in the client area of a window |
WM_RBUTTONDBLCLK |
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()
'Method for filtering the message
Public Function PreFilterMessage(ByRef m As _
System.Windows.Forms.Message) As Boolean Implements _
System.Windows.Forms.IMessageFilter.PreFilterMessage
'Blocks messages related to Window Paint event (WM_PAINT 0x000F)
If (m.Msg = &H200) Then
If Not (Form.ActiveForm) Is Nothing Then
Dim curForm As Form = Form.ActiveForm
'Search the forms in the Forms Collection to prevent
'duplication of forms in the collection
If Not (Search(curForm, frmCollection)) Then
frmCollection.Add(curForm)
AddHandler curForm.Closed, AddressOf MyForm_Closed
RaiseEvent FormFound(curForm)
End If
End If
End If
'Must return false to dispatch the Message
Return False
End Function
'Event Handler for Form Close event
Private Sub MyForm_Closed(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim k, j As Integer
'Removes the forms which are disposed
'(Form.Dispose) rather being closed(Form.Close)
For i As Integer = 0 To frmCollection.Count - 1
j = i - k
If j > (frmCollection.Count - 1) Then Exit For
'Checks the IsDisposed Property of the Form
'in the Forms Collection
If frmCollection(j).IsDisposed = True Then
frmCollection.Remove(frmCollection(j))
k = k + 1
End If
Next
'Removes the form which raised the close event
If Not (sender) Is Nothing Then frmCollection.Remove(sender)
RaiseEvent FormUnload()
End Sub
'Search Method searches fr(form) in the forms collection (frmArray)
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
Next
Return False
End Function
End Class
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()
'Use this property to access your loaded forms
Public Shared ReadOnly Property FormsCollection() As ArrayList
Get
Return FormMessageFilter.frmCollection
End Get
End Property
'Attaches FormFilter to the application
Public Sub Init()
Dim MyFilter As New FormMessageFilter
AddHandler MyFilter.FormFound, AddressOf pFormLoaded
AddHandler MyFilter.FormUnload, AddressOf pFormUnLoaded
Application.AddMessageFilter(MyFilter)
End Sub
'Called when any form is loaded in the application
Private Sub pFormLoaded(ByRef CurForm As Form)
RaiseEvent FormLoaded(CurForm)
End Sub
'Called when any form is unloaded in the application
Private Sub pFormUnLoaded()
RaiseEvent FormUnloaded()
End Sub
End Class
You have successfully created the 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 FormLoaded() and FormUnloaded() events.
Initialize the instance by calling Init() method. Init() will register AEHC for the application and starts monitoring the message queue.
In the 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 myHandler.FormsCollection.Count.
Dim WithEvents myHandler As New AEHC.ApplicationEventHandler
Public Sub main()
�Initialize the component
myHandler.Init()
Application.Run(New Form1)
End Sub
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
sender.SuspendLayout()
'Initialize the Label
label1.Font = New System.Drawing.Font("Arial", 14.25!, _
System.Drawing.FontStyle.Bold, _
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 "
'
sender.Controls.Add(label1)
sender.ResumeLayout(False)
End Sub
Private Sub myHandler_FormUnloaded() Handles myHandler.FormUnloaded
MsgBox(myHandler.FormsCollection.Count)
End Sub
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.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 11 Nov 2004 Editor: Smitha Vijayan |
Copyright 2004 by Saurabhdotnet Everything else Copyright © CodeProject, 1999-2009 Web16 | Advertise on the Code Project |