• 为应用程序添加消息过滤器


    前几天,在一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.
  • 相关阅读:
    Pandas(二)描述统计与函数应用
    Pandas(一)数据结构和基本功能
    Numpy(下)
    Numpy(上)
    42th 逻辑的连续性 取决于 细节的理解-------------我是个厨子:类的调用vs 对象调用方法
    40th 要掀桌子么 还是尬坐吧
    爱的 大循环 :我爱世界杯
    39th 迷迷糊糊 二豆玩不转了
    Python中的可迭代对象
    爱的传送带: print(.format())
  • 原文地址:https://www.cnblogs.com/michaelhuwei/p/784266.html
Copyright © 2020-2023  润新知