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)
{
if(objMessage.Msg == Convert.ToInt32(WindowsMessages.WM_KEYDOWN))
{
for(int i=0;i<marrKeysToRestrict.Length;i++)
{
in the restricted keys list
if( objMessage.WParam.ToInt32() ==
marrKeysToRestrict[i])
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.