主要問題是當消息直接發送到子控件時,表單不會收到任何消息。
解決這個問題的方法之一是註冊一個應用程序範圍的消息過濾器。請注意,下面的實現是相當低效(和相當難看),但它應該告訴你的基本思路:
void Main()
{
var form = new Form();
form.Load += (s, _) => Application.AddMessageFilter(new MyFilter((Form)s));
var pnl = new Panel();
pnl.Controls.Add(new Button());
form.Controls.Add(pnl);
Application.Run(form);
}
public class MyFilter : IMessageFilter
{
Form form;
public MyFilter(Form form)
{
this.form = form;
this.form.Disposed += (_, __) => Application.RemoveMessageFilter(this);
}
public bool PreFilterMessage(ref Message msg)
{
const int WM_LMOUSEDOWN = 0x0201;
if (msg.Msg == WM_LMOUSEDOWN && msg.HWnd != IntPtr.Zero
&& Control.FromHandle(msg.HWnd).TopLevelControl == form)
{
Console.WriteLine("Hi!");
}
return false;
}
}
'KeyDown'不是鼠標相關的事件。也許你想使用['MouseDown'](https://msdn.microsoft.com/en-us/library/ms171542(v = vs.110).aspx)? – Sinatr
您將遇到與MouseDown相同的問題。無論您將鼠標懸停在哪個控件上,都將獲得鼠標事件。如果這是一個按鈕,它會得到鼠標事件。如果沒有控制權,那將是形式本身。您需要在適當的控制下處理事件。 –
@Sinatr否,它的行爲與PlayForm_Click()相同 –