C#在win10和非Win10上处理鼠标滚动有一些区别,建一个Form1,放置一个FlowLayoutPanel ,类型的Panel1
Panel.MouseWheel += PanelOnMouseWheel; private void PanelOnMouseWheel(object sender, MouseEventArgs mouseEventArgs) { if (mouseEventArgs.Delta < 0) ScrollBar.Value = ScrollBar.Value == ScrollBar.Maximum ? ScrollBar.Maximum : ++ScrollBar.Value; else ScrollBar.Value = ScrollBar.Value == ScrollBar.Minimum ? ScrollBar.Minimum : --ScrollBar.Value; }
以上代码在win10上,只要鼠标在Panel1客户区范围内,那么滚动鼠标滚轮时,就能触发滚动事件,但是在非win10上,如果焦点不在Panel上,比如在Form1窗体一个Button上,那么就不能触发滚动事件。
解决办法
[DllImport("user32.dll")] public static extern IntPtr GetFocus();
需要判断焦点按钮是否是本窗口子控件,使用IMessageFilter。
const int WM_MOUSEWHEEL = 0x020A; [DllImport("user32.dll")] public static extern IntPtr WindowFromPoint(int xPoint, int yPoint); public bool PreFilterMessage(ref Message msg) { if (msg.Msg == WM_MOUSEWHEEL) { IntPtr hWnd = WindowFromPoint(MousePosition.X, MousePosition.Y); if ((CheckControl(this, hWnd))) { int wpara = (int)msg.WParam; //this.Parent.Parent.Text = "wparam:" + wpara.ToString() + ", msg:" + msg.Msg + ",hwnd:" + msg.HWnd.ToString(); // MessageBox.Show("123"); if ((wpara & 0x80000000) == 0x80000000)//向下 ScrollBar.Value = ScrollBar.Value == ScrollBar.Maximum ? ScrollBar.Maximum : ++ScrollBar.Value; else ScrollBar.Value = ScrollBar.Value == ScrollBar.Minimum ? ScrollBar.Minimum : --ScrollBar.Value; } return false; } return false; }
public bool CheckControl(Control control, IntPtr handle) { if (control == null) return false; try { for (int i = 0; i < control.Controls.Count; i++) { var v = control.Controls[i]; if (handle == v.Handle) { return true; } else { if (v.Controls.Count > 0) { if (CheckControl(v, handle)) { return true; } } } } } catch (Exception e) { Console.WriteLine(e); return false; } return false; }
如果有更好的解决办法请指点。
为了提示查找效率,可以使用下面函数
public static bool CheckIsParentControl(Control parentControl, Control childControl) { if(childControl==null)return false; if (childControl.Parent == null) { return false; } if (childControl.Parent == parentControl) { return true; } return CheckIsParentControl(parentControl, childControl.Parent); }