在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

Windows消息过滤的更多相关文章

  1. Windows消息机制详解

    消息是指什么?      消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...

  2. 【转】windows消息和消息队列详解

    转载出处:http://blog.csdn.net/bichenggui/article/details/4677494  windows消息和消息队列 与基于MS - DOS的应用程序不同,Wind ...

  3. Windows消息机制概述

    消息是指什么?     消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用程 ...

  4. windows消息和消息队列

    windows消息和消息队列 转自:http://blog.163.com/zhangjie_0303/blog/static/990827062010113062446767/ 与基于MS - DO ...

  5. Windows 消息机制详解

    总的来说: MSG包括: 窗口句柄,指示MSG发送的目的窗口 消息标识 lPARAM.wParam 发送时间 发送时的鼠标位置   关于消息队列: Windows系统有一个系统消息队列 每个线程都有一 ...

  6. 【Qt】Qt之进程间通信(Windows消息)【转】

    简述 通过上一节的了解,我们可以看出进程通信的方式很多,今天分享下如何利用Windows消息机制来进行不同进程间的通信. 简述 效果 发送消息 自定义类型与接收窗体 发送数据 接收消息 设置标题 重写 ...

  7. Qt之进程间通信(Windows消息)

    简述 通过上一节的了解,我们可以看出进程通信的方式很多,今天分享下如何利用Windows消息机制来进行不同进程间的通信. 简述 效果 发送消息 自定义类型与接收窗体 发送数据 接收消息 设置标题 重写 ...

  8. windows消息钩子

    1.消息钩子的概念: Windows应用程序是基于消息驱动的,不论什么线程仅仅要注冊窗体类都会有一个消息队列用于接收用户输入的消息和系统消息.为了拦截消息,Windows提出了钩子的概念.钩子(Hoo ...

  9. Windows消息编程(写的不错,有前因后果)

    本文主要包括以下内容: 1.简单理解Windows的消息2.通过一个简单的Win32程序理解Windows消息3.通过几个Win32程序实例进一步深入理解Windows消息4.队列消息和非队列消息5. ...

随机推荐

  1. function中的ajax怎么返回一个数

  2. html EVENT对象

    Event 对象 Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件通常与函数结合使用,函数不会在事件发生前被执行! onabort 图像的加 ...

  3. centos x86_64环境下 下载chrome

    由于Cent OS内核版本过低,无法安装Chrome浏览器2.替代方案:可以使用Chromium浏览器 1.切换到root: su - 或者 sudo -i 2.下载新的软件源定义: cd /etc/ ...

  4. [C++] Running time and Integer to String

    std::string num2str(int64_t p_vint, int8_t p_radix) { char str[48] = { 0 }; int64_t temp = 0; int64_ ...

  5. final发布评价

    1.飞天小女警: 礼物挑选这个项目相比之前的发布功能更完善了些,但是整体界面还是不太美观,界面上呈现出的选项字不够清晰,最为最终产品其功能还是少了点儿.在发布过程中整体表达比较清晰.流畅,比较不错. ...

  6. Thread系列之Thread.Sleep(0)

    线程这一概念,可以理解成进程中的一个小单元.这个单元是一个独立的执行单元,但是与进程中的其他线程共享进程中的内存单元. 由于Cpu资源是有限的,所以进程中的多个线程要抢占Cpu,这也导致进程中的多个线 ...

  7. div四个边框分别设置阴影样式

    对于div边框的阴影一直没有很好地理解,也一直不明白怎么给四个边框分别设置阴影.昨天项目中碰到了这个问题,就认真想了一下,在此总结一二. 首先,还是从官方解释说起. 网上的解释通常都是什么水平阴影长度 ...

  8. IE下被遮住的iframe能接收事件

    今天,2012-2-22,是个很二的日子,遇到了一个诡异的问题~~ 下午收到一封信. from:someone@ctrip.comto:小灰灰title:被挡住的iframe也能接收到点击事件小灰灰, ...

  9. 深度学习框架 Torch 7 问题笔记

    深度学习框架 Torch 7 问题笔记 1. 尝试第一个 CNN 的 torch版本, 代码如下: -- We now have 5 steps left to do in training our ...

  10. BarTender是怎么做出雪花状文字

    一些小伙伴在做标签时,发现有的人做的标签上的文字颜色不是纯色的,问我是怎么做的.这种雪花状文字要设置出来其实很简单,只要用到字体颜色填充工具就可以了.下面,小编就来给大家简单介绍一下BarTender ...