某 Panel 內的 TextBox 僅允許滑鼠右鍵「複製」功能,且不影響其他 Panel 內的 TextBox。一般做法無法精確攔截特定控制項的滑鼠訊息,需使用全域鉤子。
完整程式碼較長,核心架構如下:
SetWindowsHookEx、CallNextHookEx、UnhookWindowsHookEx 等 Win32 API。POINT、MouseHookStruct、MouseLLHookStruct、KeyboardHookStruct 等結構。WH_MOUSE_LL = 14) 與鍵盤鉤子 (WH_KEYBOARD_LL = 13)。MouseHookProc 解析滑鼠訊息 (按下/釋放/滾輪/雙擊),轉換為 .NET MouseEventArgs 引發 OnMouseActivity 事件。KeyboardHookProc 處理鍵盤訊息,支援 KeyDown/KeyPress/KeyUp 事件。
public class Form1 : Form
{
private TextBox textBox1; // 僅允許複製
private TextBox textBox2; // 正常
private Panel panel1; // 包含 textBox1
private UserActivityHook _hook;
private void Form1_Load(object sender, EventArgs e)
{
_hook = new UserActivityHook();
_hook.OnMouseActivity += Choose_OnMouseActivity;
}
private void Choose_OnMouseActivity(object sender, MouseEventArgs e)
{
if (ActiveControl == textBox1 && e.Button == MouseButtons.Right)
{
var copy = new MenuItem("Copy");
copy.Click += (s, args) => Clipboard.SetDataObject(textBox1.SelectedText);
textBox1.ContextMenu = new ContextMenu(new[] { copy });
}
}
protected override void Dispose(bool disposing)
{
if (disposing) _hook?.Stop(true, true, true);
base.Dispose(disposing);
}
}
此鉤子實現存在嚴重問題:同一進程中同一時間只能有一個視窗使用鉤子。若開啟第二個使用鉤子的視窗而未正確關閉第一個,會導致系統訊息迴路錯亂,後果嚴重 (可能造成系統無回應)。生產環境請謹慎評估,或改用子類別化 /
IMessageFilter/ 控制項層級事件處理等替代方案。