Windows 以訊息驅動模型運作,所有 UI 互動 (點擊、鍵盤、繪圖) 皆透過訊息傳遞。C# 可透過 P/Invoke 呼叫 SendMessage 發送訊息,並重寫 DefWndProc 接收處理。
public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_USER = 0x0400; // 自訂訊息基底
public const int MY_CUSTOM_MSG = WM_USER + 1;
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
protected override void DefWndProc(ref Message m)
{
switch (m.Msg)
{
case WM_LBUTTONDOWN:
MessageBox.Show($"滑鼠左鍵: wParam={m.WParam}, lParam={m.LParam}");
break;
case MY_CUSTOM_MSG:
// 處理自訂訊息
break;
default:
base.DefWndProc(ref m); // 交由基類處理
break;
}
}
實作 IMessageFilter 可在訊息分派前全域攔截 (類似 MFC 子類化):
public class MyForm : Form, IMessageFilter
{
const int WM_MOUSEMOVE = 0x0200;
public MyForm()
{
Application.AddMessageFilter(this); // 註冊
}
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_MOUSEMOVE)
{
// 攔截滑鼠移動,回傳 true 表示已處理,不再分派
return true;
}
return false;
}
protected override void Dispose(bool disposing)
{
if (disposing) Application.RemoveMessageFilter(this);
base.Dispose(disposing);
}
}
PostMessage 非同步)SendMessage 同步阻塞,PostMessage 非同步佇列。wParam/lParam 在 64 位系統為 IntPtr,需正確封送。