zoukankan      html  css  js  c++  java
  • 为应用程序添加消息过滤器

    前几天,在一QQ群上,有一网友提问:如何得到鼠标按下时,点中的是哪个控件。(不能在每个控件的事件中添加 OnMouseDown,因为这样太麻烦,而且控件可能是动态产生的)

    当时我的第一反应是:这还不简单,直接重载 Form 的 WndProc 事件就行了

            const int WM_LBUTTONDOWN = 0x0201;
            
    protected override void WndProc(ref Message m)
            {
                
    if (m.Msg == WM_LBUTTONDOWN)
                {
                    Console.WriteLine(Control.FromHandle(m.HWnd).Name);
                }
                
    base.WndProc(ref m);
            }
    实际运行才发现根本不是那么回事,当我在一个 TextBox 上按下鼠标时,Form的WndProc根本不会执行。
    静下来好好想想,才发现自已错在对 WndProc 的理解上, Control.WndProc接收的消息仅仅是发送给该 Control 的,已经被操作系统过滤过的,所以当鼠标点在 TextBox 上时,Form 当然收不到 WM_LBUTTONDOWN 消息.

    那假如要实现该功能,要怎么办呢,经查, 用Application.AddMessageFilter 方法可实现,具体代码为:
    1.先定义一个消息过滤器
        /// <summary>
        
    /// 自定义的消息过滤器,必须实现 IMessageFilter 接口
        
    /// </summary>
        class myFilter : IMessageFilter
        {
            
    const int WM_LBUTTONDOWN = 0x0201;
            
    public bool PreFilterMessage(ref Message m)
            {
                
    if (m.Msg == WM_LBUTTONDOWN)
                {
                    Console.WriteLine(Control.FromHandle(m.HWnd).Name);
                }
                
    return false;
            }
        }
    2.在Form中添加该过滤器
            private void Form1_Load(object sender, EventArgs e)
            {
                
    //为窗体添加消息过滤器
                Application.AddMessageFilter(new myFilter());
            }
    经过这两步后,任何消息都会先发送到 myFilter 中, 用户可处理其中自已感兴趣的消息,OK!

    注:msdn 上明确注明,AddMessageFilter 会让系统性能下降,估计其低层是用 SetWindowsHook之类的API.
  • 相关阅读:
    Python--面向对象编程
    Python--私有
    Python--格式化cookie为字典类型
    Python--异常处理
    Python--加密小练习
    bzoj 1774: [Usaco2009 Dec]Toll 过路费
    lougu T7983 大芳的逆行板载
    bzoj 1083(&vijos 1190): [SCOI2005]繁忙的都市 && bzoj 1601: [Usaco2008 Oct]灌水
    vijos 1083 小白逛公园
    51nod 1766 树上的最远点对
  • 原文地址:https://www.cnblogs.com/michaelhuwei/p/784266.html
Copyright © 2011-2022 走看看