某些特殊需求下,需要在應用程式層級攔截或屏蔽特定滑鼠訊息,例如:
ListBox)。System.Windows.Forms.Application 提供訊息泵機制,透過實作 IMessageFilter 介面並註冊至 Application.AddMessageFilter(),即可在訊息分發至控制項前進行預處理。
using System;
using System.Windows.Forms;
public class MouseMessageFilter : IMessageFilter
{
// 攔截 WM_RBUTTONDOWN (0x204) 等滑鼠訊息
public bool PreFilterMessage(ref Message m)
{
// 常見滑鼠訊息常數
const int WM_LBUTTONDOWN = 0x0201;
const int WM_RBUTTONDOWN = 0x0204;
const int WM_MBUTTONDOWN = 0x0207;
const int WM_MOUSEMOVE = 0x0200;
// 示例:屏蔽右鍵點擊
if (m.Msg == WM_RBUTTONDOWN)
{
// 返回 true 表示訊息已被處理,不再分發給控制項
return true;
}
// 如需屏蔽所有滑鼠按鍵,可擴展判斷邏輯
// if (m.Msg >= WM_LBUTTONDOWN && m.Msg <= WM_MBUTTONDOWN) return true;
return false; // false 表示繼續正常分發
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var filter = new MouseMessageFilter();
Application.AddMessageFilter(filter); // 註冊過濾器
try
{
Application.Run(new Form1());
}
finally
{
Application.RemoveMessageFilter(filter); // 確保移除,避免記憶體洩漏
}
}
}
| 項目 | 說明 |
|---|---|
PreFilterMessage 返回值 | true = 訊息被攔截/消費;false = 繼續傳遞 |
| 訊息常數 | 定義於 WinUser.h,常用滑鼠訊息見代碼註釋 |
| 作用範圍 | 全應用程式範圍,所有視窗的訊息泵均會經過此過濾器 |
| 執行時機 | 訊息分發給 Control.WndProc 之前 |
若僅想屏蔽特定控制項(如 listBox1)的滑鼠事件,可在 PreFilterMessage 中判斷 m.HWnd:
public bool PreFilterMessage(ref Message m)
{
if (m.HWnd == listBox1.Handle &&
(m.Msg == WM_LBUTTONDOWN || m.Msg == WM_RBUTTONDOWN))
{
return true; // 僅攔截 listBox1 的滑鼠按下
}
return false;
}
RemoveMessageFilter,否則可能導致殘留引用。ComponentDispatcher.ThreadFilterMessage 事件,機制不同。