新聞速報

        

2014年8月29日 星期五

IMessageFilter 與WndProc(ref Message e)有什麼區別?

請問一個小問題
一:誰用過  IMessageFilter ?怎麼用的?
二:IMessageFilter 與WndProc(ref Message e)有什麼區別?
謝謝大哥大姐們,
不勝感激?

解決方案 »

  1. public partial class Form1 : Form, IMessageFilter
        {
            public Form1()
            {
                InitializeComponent();            Application.AddMessageFilter(this);
            }        public bool PreFilterMessage(ref Message m)
            {
                if (m.Msg ==...)
                {
                    ...
                }
            }
        }
    IMessageFilter  攔截應用程序所有消息
    WndProc 攔截本窗口消息
      
  2. IMessageFilter應該是過濾消息的,而WndProc(ref Message e)則是捕獲消息並自定義處理。當然,在這裡我說一下WndProc(ref Message e),這個重寫參數是ref修飾的那麼除捕獲外,當然也可以修改消息的內容。具體你可以查看MSDN,這個函數很有用的。
      
  3. IMessageFilter  攔截應用程序所有消息
    WndProc 攔截本窗口消息
    我發現IMessageFilter不能攔截wm_close
    而WndProc 可以
    為什麼呀
      
  4. 因為在關閉窗口時消息的順序是倒過來的,肯定是窗口自己的消息循環先捕獲到這個消息麼,要拋出來才能被外面的application捕獲到
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;namespace WindowsFormsApplication11
    {
        public partial class Form1 : Form, IMessageFilter
        {
            int WM_CLOSE = 0x0010;
            public Form1()
            {
                InitializeComponent();            Application.AddMessageFilter(this);            this.KeyPreview = true;
            }        public bool PreFilterMessage(ref Message m)
            {
                if (m.Msg == WM_CLOSE)
                {
                    MessageBox.Show("不許關閉。");
                    return true;
                }
                else
                    return false;
            }        protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_CLOSE)
                    Application.FilterMessage(ref m);
                else
                    base.WndProc(ref m);
            }
        }
    }
      
  5. 對了 this.KeyPreview = true;
     是多余的
      
  6. IMessageFilter 是消息預處理的一部分,所以它收到的消息是更全的
    WndProc 繼承自Control,收到針對本窗口自身的消息
    使用參考
    http://social.msdn.microsoft.com/forums/en-US/winforms/thread/93283ae1-6673-4470-ba46-8313215b92cb/
      
  7. 補充一下,准確的說,wm_create,wm_close之類窗口消息都被wndproc吃掉了
    而鼠標左鍵你會看到是imessagefilter先捕獲到
    現在居然不能連續發貼3次以上
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;namespace WindowsFormsApplication11
    {
        public partial class Form1 : Form, IMessageFilter
        {
            int WM_LBUTTONDOWN = 0x0201;        public Form1()
            {
                InitializeComponent();            Application.AddMessageFilter(this);
            }        public bool PreFilterMessage(ref Message m)
            {
                if (m.Msg == WM_LBUTTONDOWN)
                    MessageBox.Show("PreFilterMessage - WM_LBUTTONDOWN");
                return false;
            }        protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_LBUTTONDOWN)
                    MessageBox.Show("WndProc - WM_LBUTTONDOWN");
                base.WndProc(ref m);
            }
        }
    }在form上點擊
    先彈出 PreFilterMessage - WM_LBUTTONDOWN
    再彈出 WndProc - WM_LBUTTONDOWN

沒有留言:

張貼留言