• Windows消息过滤


    在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();
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [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

  • 相关阅读:
    基于jQuery仿淘宝产品图片放大镜代码
    【家育通】 关于我们
    新房装修三大空鼓解决方法 为家居装修做好前奏
    MVC5+EF6 入门完整教程十一:细说MVC中仓储模式的应用
    MVC5+EF6 入门完整教程十
    MVC5+EF6 入门完整教程九
    MVC5+EF6 入门完整教程八
    MVC5+EF6 入门完整教程七
    MVC5+EF6 入门完整教程六
    MVC5+EF6 入门完整教程五
  • 原文地址:https://www.cnblogs.com/lenmom/p/3730173.html
Copyright © 2020-2023  润新知