Windows消息过滤

2020-11-27 05:26

阅读:554

标签:style   blog   class   c   ext   color   

在C#编程中,经常会遇到一些场景,如禁止鼠标拖动窗体,启用某些快捷键,禁止鼠标移动等。遇到这些需求,可以通过窗体的MouseMove事件,OnDragDrop,OnMove等事件来解决问题,

但是该方法有个缺点是,只能在当前窗体或控件上起作用,如果窗体或控件被覆盖,就不起作用了。而我们在开发时经常会碰到一个Form上有很多控件的情形,本节将讲述如何通过捕捉windows消息的方式来实现这个功能。

一般来讲,实现该功能有两种方法,

1. 通过重写WndProc(ref Message m)来实现,方法签名如下:

protected override void WndProc(ref Message m)
{
      base.WndProc(ref m);
}

 

其中的Message中包含了以下几个字段信息,是和windows消息相关的,

       public IntPtr LParam { get; set; }

        public int Msg { get; set; }  // 获取或设置消息的 ID 号。

        public IntPtr WParam { get; set; }

如:

如果我们要禁用窗体的拖拽,代码如下:

      const int WM_NCLBUTTONDOWN = 0x00A1;
      const int HTCAPTION = 2;
      protected override void WndProc(ref Message m)
      {
              if (m.Msg == WM_NCLBUTTONDOWN && m.WParam.ToInt32() == HTCAPTION)
                     return; 
              base.WndProc(ref m);
      }

 

2. 通过继承接口来实现System.Windows.Forms.IMessageFilter接口实现,接口声明如下:

public interface IMessageFilter
{
     // 摘要:
    // 在调度消息之前将其筛选出来。
    //
    // 参数:
    // m:
    // 要调度的消息。无法修改此消息。
    //
   // 返回结果:
   // 如果筛选消息并禁止消息被调度,则为 true;如果允许消息继续到达下一个筛选器或控件,则为 false。
   bool PreFilterMessage(ref Message m);
}

 

还以禁止拖动窗体为例,实现MessageFilter类如下:

public class MessageFilter : System.Windows.Forms.IMessageFilter
    {
        const int WM_NCLBUTTONDOWN = 0x00A1;//当光标在窗口的非客户区并按下鼠标左键时发送此消息
        const int HTCAPTION = 2;
 
        public bool PreFilterMessage(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == WM_NCLBUTTONDOWN && m.WParam.ToInt32() == HTCAPTION)
                return true;
            return false;
        }
    }

 

 创建完这个类后,创建一个对象,并把该对象添加到应用程序里边,如下列代码,下列代码是Program文件当中的入口方法
  static class Program
    {
        private static MessageFilter filter = new MessageFilter();
        ///
        /// 应用程序的主入口点。
        ///
        [STAThread]
        static void Main()
        {
            Application.AddMessageFilter(filter);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainFrm());
        }
    }  

 

注意:实现IMessageFilter接口时,一定要注意其返回值, [如果筛选消息并禁止消息被调度,则为 true;如果允许消息继续到达下一个筛选器或控件,则为 false。] ,对拦截的消息处理之后,一定要注意对返回值进行处理,如果对不处理的消息,一定要返回为false,让其他的控件去处理消息。

 

关于Windows消息,请参考文章 http://www.cnblogs.com/lenmom/p/3730179.html

Windows消息过滤,搜素材,soscw.com

Windows消息过滤

标签:style   blog   class   c   ext   color   

原文地址:http://www.cnblogs.com/lenmom/p/3730173.html


评论


亲,登录后才可以留言!