[英]Detect Mouse Wheel on a button
我有以下控制層次結構
Form
TabControl
Panel
Button
我正在嘗試檢測按鈕上的鼠標滾輪事件。 我知道要讓控件捕獲鼠標滾輪事件,它必須處於焦點狀態,而我的按鈕當前未處於焦點位置?
我首先將滾輪事件附加到面板,然后附加到按鈕,但是在這兩種情況下它都不會檢測到該事件,可能是因為它不在焦點上。
現在我已將偶數附加到表單上,並且表單檢測到輪事件
this.MouseWheel +=Form1_MouseWheel;
然后我嘗試使用以下代碼檢測鼠標下的孩子
private void Form1_MouseWheel(object sender, MouseEventArgs e) {
if (e.Delta > 0) {
Debug.WriteLine("SCROLL UP..." + e.Delta);
} else {
Debug.WriteLine("SCROLL DOWN..." + e.Delta);
}
Control ctrl = this.GetChildAtPoint(e.Location);
if (ctrl != null) {
Debug.WriteLine("Wheeling Over " + ctrl.Name);
}
}
但是,代碼僅打印tabControl1
。
有沒有一種方法可以讓孩子更深入層次結構,並在鼠標滾輪處於活動狀態時獲得當前位於鼠標下方的正確Control
?
Button 必須是 Active Control 才能引發MouseWheel
事件。
Control.GetChildAtPoint返回 Control 的直接子級,從中調用方法,包含 Mouse position(這也可能取決於使用的系統版本)。
如果可以 PInvoke,則可以使用WindowFromPoint檢測當前位於鼠標指針 position 下的 Control。 考慮您可以在文檔中找到的注釋:
返回值是包含該點的 window 的句柄。 如果給定點不存在 window,則返回值為 NULL。 如果該點位於 static 文本控件上方,則返回值是 static 文本控件下的 window 的句柄。
▲ 不適用於 WinForms 標簽,這些確實返回一個句柄。
注意: WindowFromPoint
不會返回所有控件的句柄:
function 不返回不可見或禁用的控件句柄。
如果可以滾動的控件(TextBoxes、RichTextBoxes)具有捕獲(控件處於活動狀態並包含插入符號),您將不會收到 MouseWheel 事件,因為這些事件是由控件接收的,而不是由窗體接收的。
某些控件無法返回句柄:ComboBox 的 TextBox 與DropDownStyle = DropDown
和 ToolStripProgressBar(例如)。
您可能還想看看ChildWindowFromPointEx和RealChildWindowFromPoint 。
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr WindowFromPoint(Point point);
internal const int WM_MOUSEMOVE = 0x0200;
internal const int WM_MOUSEWHEEL = 0x020A;
internal const int WM_MOUSEHWHEEL = 0x020E;
internal const int WM_MOUSEHOVER = 0x02A1
使用返回的句柄WindowFromPoint
覆蓋表單的WndProc
並使用Control.FromFandle()獲取鼠標指針下的控件。
鼠標指針的當前屏幕 position 由MousePosition或Cursor.Position返回(兩者都返回與位置相關的相同值)。
我還添加了WM_MOUSEHWHEEL
以及WM_MOUSEMOVE
和WM_MOUSEHOVER
,注釋掉了:您可能需要它們。
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg) {
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
Point pos = MousePosition;
Console.WriteLine($"Position: {pos}");
Console.WriteLine($"Delta: {(short)(m.WParam.ToInt32() >> 16)}");
Console.WriteLine($"Mouse Button: {(short)m.WParam.ToInt32()}");
IntPtr hWnd = WindowFromPoint(pos);
if (hWnd != IntPtr.Zero) {
var control = Control.FromHandle(hWnd);
Console.WriteLine($"Handle: {hWnd}");
Console.WriteLine($"Control Name: " + control?.Name);
}
m.Result = IntPtr.Zero;
break;
//case WM_MOUSEMOVE:
// //Console.WriteLine($"{Control.ModifierKeys}");
// m.Result = IntPtr.Zero;
// break;
//case WM_MOUSEHOVER:
// //Console.WriteLine($"{Control.ModifierKeys}");
// m.Result = IntPtr.Zero;
// break;
}
您是否確保將 MouseEventHandler 附加到按鈕? 我嘗試了以下代碼,它按預期工作。 (此代碼包括所描述的 Form > TabControl > Panel > Button。)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.MouseWheel += new MouseEventHandler(Button1_MouseWheel);
}
public void Button1_MouseWheel(object sender, MouseEventArgs e)
{
Debug.WriteLine("ButtonWheel");
MessageBox.Show("ButtonWheel");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.