// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections.Generic;
using System.Drawing;
private readonly List<Control> controls = new List<Control>();
public MouseWheelMessageFilter()
- {
- Application.AddMessageFilter(this);
- }
+ => Application.AddMessageFilter(this);
public void Register(Control target)
- {
- this.controls.Add(target);
- }
+ => this.controls.Add(target);
public void Unregister(Control target)
- {
- this.controls.Remove(target);
- }
+ => this.controls.Remove(target);
public bool PreFilterMessage(ref Message m)
{
{
foreach (var control in this.controls)
{
- // フォーカスが当たっている時は何もしなくても MouseWheel イベントが発生するので無視
- if (control.Focused)
- return false;
-
- var screenLocation = new Point((int)m.LParam);
+ var details = ParseMessage(m);
var controlRectangle = control.Parent.RectangleToScreen(control.DisplayRectangle);
- if (controlRectangle.Contains(screenLocation))
+ if (controlRectangle.Contains(details.ScreenLocation))
{
- var clientLocation = control.PointToClient(screenLocation);
- var wheelDelta = (int)m.WParam >> 16;
+ var clientLocation = control.PointToClient(details.ScreenLocation);
- var ev = new HandledMouseEventArgs(MouseButtons.None, 0, clientLocation.X, clientLocation.Y, wheelDelta);
+ var ev = new HandledMouseEventArgs(MouseButtons.None, 0, clientLocation.X, clientLocation.Y, details.WheelDelta);
this.RaiseMouseWheelEvent(control, ev);
+ // フォーカスが当たっているか否かに関わらず OnMouseWheel イベントを発生させているため、
+ // 二重にイベントが発生することを防ぐために標準のメッセージ処理は抑制する
return true;
}
}
return false;
}
+ internal class MouseEvent
+ {
+ public Point ScreenLocation { get; }
+ public int WheelDelta { get; }
+
+ public MouseEvent(Point location, int delta)
+ {
+ this.ScreenLocation = location;
+ this.WheelDelta = delta;
+ }
+ }
+
+ internal static MouseEvent ParseMessage(Message m)
+ {
+ var screenLocation = new Point((int)(m.LParam.ToInt64() & 0xffffffff));
+ var wheelDelta = (int)(m.WParam.ToInt64() & 0xffff0000) >> 16;
+
+ return new MouseEvent(screenLocation, wheelDelta);
+ }
+
public void RaiseMouseWheelEvent(Control control, MouseEventArgs e)
{
var method = typeof(Control).GetMethod("OnMouseWheel", BindingFlags.Instance | BindingFlags.NonPublic);