65.9K
CodeProject is changing. Read more.
Home

Using IMessageFilter to create a generic filter for operating system events

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.55/5 (8 votes)

Oct 16, 2003

1 min read

viewsIcon

113074

downloadIcon

1495

An article on implementing IMessageFilter to create a message filter for operating system messages

Introduction

The IMessageFilter class in .NET framework allows an application to capture a windows OS message before it is dispatched to a control or form. A class that implements the IMessageFilter interface can be added to the application's message pump to filter out a message or perform other operations before the message is dispatched to a form or control. Disabling the keys at the forms level leads to lot of code repetition and something that doesn’t look very elegant. The solution provides a generic solution to the problem by separating the implementation from the UI.

Background

The requirement that lead to this solution was, conditional Enabling/Disabling specified keys on a windows form.

Using the code

On click of button3 the keys passed are disabled and enabled again on click of button4. Although the solution addresses the Key_Pressed event only, it can be extended to filter any operating system event.

private void button3_Click(object sender, System.EventArgs e) 
{ 
  mobjMessageFilter = new MessageFilter(); 
  mobjMessageFilter.KeysToRestrict=new int[]{
    Convert.ToInt32(MessageFilter.VirtualKeys.VK_F2), 
    Convert.ToInt32(MessageFilter.VirtualKeys.VK_F1)}; 
  Application.AddMessageFilter(mobjMessageFilter); 
}
 
private void button4_Click(object sender, System.EventArgs e) 
{ 
  Application.RemoveMessageFilter(mobjMessageFilter); 
} 

The MessageFilter Class

MessgeFilter class implements the IMessageFilter interface and gives the concrete implementation of the Message Filter.

public class MessageFilter:IMessageFilter

The VirtualKeys enumeration

This Enumeration contains virtual key values sent by the operating system when a key is pressed.

public enum VirtualKeys : int 
{ 
VK_LBUTTON = 0x01, 
VK_RBUTTON = 0x02, 
VK_CANCEL = 0x03, 
VK_MBUTTON = 0x04, 
VK_XBUTTON1 = 0x05, 
VK_XBUTTON2 = 0x6, 
VK_BACK = 0x08, 
VK_TAB = 0x09, 
VK_RETURN = 0x0D, 
VK_SHIFT = 0x10, 
VK_CONTROL = 0x11, 
VK_ESCAPE = 0x1B, 
VK_SPACE = 0x20, 
VK_LEFT = 0x25, 
VK_UP = 0x26, 
VK_RIGHT = 0x27, 
VK_DOWN = 0x28, 
VK_DELETE = 0x2E, 
VK_F1 = 0x70, 
VK_F2 = 0x71, 
VK_F3 = 0x72, 
VK_F4 = 0x73, 
VK_F5 = 0x74, 
VK_F6 = 0x75, 
VK_F7 = 0x76, 
VK_F8 = 0x77, 
VK_F9 = 0x78, 
VK_F10 = 0x79, 
VK_F11 = 0x7A, 
VK_F12 = 0x7B, 
VK_F13 = 0x7C, 
VK_F14 = 0x7D, 
}

The WindowsMessages enumeration

This enumeration contains the WindowsMessage value for various Operating System events. Included code contains an exhaustive listing of windows messages.

private enum WindowsMessages: int 
{ 
WM_KEYDOWN = 0x0100 
}

And now to the implementation of the MessageFilter class. It in fact is very simple, all we have to do is give an implementation for the PreFilterMessage method, I have created a property int[] KeysToRestrict to accept the values of the keys to be filtered. And here is what the method looks like,

private enum WindowsMessages: int
{
  WM_KEYDOWN = 0x0100
}

public bool PreFilterMessage(ref Message objMessage)
{
  //Check if the Message is a windows Key down message
  if(objMessage.Msg == Convert.ToInt32(WindowsMessages.WM_KEYDOWN))
  {
    for(int i=0;i<marrKeysToRestrict.Length;i++)
    {
      //Check if the Message's WParam(the key value) is 
in the restricted keys list
      if( objMessage.WParam.ToInt32() == 
marrKeysToRestrict[i])
      //Disable message propagation
      return true;
    }
  }
 return false;
} 

The method returns true if the Message objects WParam property is equal to any element in the array thus disabling the key.