The WndProc & How To Disable (Ignore) Button Click Event

26 בנובמבר 2008

תגיות: ,
2 תגובות

Intro

So, the idea behind this post is to show you guys, how to disable the click event of a .NET button, but first thing first and lets start with a little review of the Control class.

Every Button in .NET eventually inherits from a base class Control. The Control class has a virtual method defined:

protected virtual void WndProc(ref Message m);

This method is basically a the location we hook up to windows notifications. There are a lot of types for window notifications, for example:

  • WM_SIZING – The WM_SIZING message is sent to a window that the user is resizing. By processing this message, an application can monitor the size and position of the drag rectangle and, if needed, change its size or position.
  • WM_MOVE – The WM_MOVE message is sent after a window has been moved.
  • WM_CLOSE – The WM_CLOSE message is sent as a signal that a window or an application should terminate.

You can find the complete list of notification here.

The Message Struct

All the notifications are received in the WndProc method using a message struct:

 
    public struct Message
    {
        public static bool operator !=(Message a, Message b);
        public static bool operator ==(Message a, Message b);
        public IntPtr HWnd { get; set; }
        public IntPtr LParam { get; set; }
        public int Msg { get; set; }
        public IntPtr WParam { get; set; }
        public static Message Create(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam);
        public override bool Equals(object o);
        public override int GetHashCode();
 
        public object GetLParam(Type cls);
        public override string ToString();
    } 

One important thing to notice is the :

public int Msg { get; set; }

This is id number of the message (notification). So basically when we get a new message we can investigate the Msg and understand what type of notification it is. Every notification can be converted to int, thus we can compare the Msg with a notification and add or replace the default behavior for a given notification. Later on in our example we will replace the default click event…

Lets take a look at the Control's WndProc implementation:

protected virtual void WndProc(ref Message m)
{
    if ((this.controlStyle & ControlStyles.EnableNotifyMessage) == ControlStyles.EnableNotifyMessage)
    {
        this.OnNotifyMessage(m);
    }
    switch (m.Msg)
    {
        case 1:
            this.WmCreate(ref m);
            return;
 
        case 2:
            this.WmDestroy(ref m);
            return;
 
        case 3:
            this.WmMove(ref m);
            return;
 
        case 7:
            this.WmSetFocus(ref m);
            return;
 
        case 8:
            this.WmKillFocus(ref m);
            return;
 
        case 15:
            if (!this.GetStyle(ControlStyles.UserPaint))
            {
                this.DefWndProc(ref m);
                return;
            }
            this.WmPaint(ref m);
            return;
 
            }
       //And so on....
    }
}

As you can see, the WndProc method is build on a long switch statement, where on each case there is a different handler.

Disable The Left Click Event

In order to do that we need to follow this steps:

  1. Create a class that inherits from button control.
  2. Override the WndProc method.
  3. Check if the notifucation we get within the message is the user clicked event and if so ignore this message.

Simple, right?

One thing that we must first know is the message id for left mouse click:

public const int WM_LBUTTONDOWN = 0x0201;

Now, lets see the entire class:

public class IgnoreClickButton : Button
{
    public const int WM_LBUTTONDOWN = 0x0201;
 
    public IgnoreClickButton()
    {
        
    }
 
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == (int)WM_LBUTTONDOWN)
        {
            return;
        }
 
        base.WndProc(ref m);
    }
}

That is it. Now, every time that a left click occur, we will ignore it. Cool, ahhh?

 
הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

2 תגובות

  1. Maor David-Pur26 בנובמבר 2008 ב 15:19

    קולביס גיא, דבר איתי בבקשה על דוגמאות קוד. אני לא אוהב את איך שזה נראה בבלוג שלך. אעזור לך לשפר.
    תודה

    להגיב
  2. kolbis27 בנובמבר 2008 ב 3:11

    sorry for the format. it seems that the Code snippet plugin to live writer has some issues. I will fix it!

    להגיב