diff --git a/Src/SourceGrid/Common/CustomScrollControl.cs b/Src/SourceGrid/Common/CustomScrollControl.cs index 10664fe..2822dd3 100644 --- a/Src/SourceGrid/Common/CustomScrollControl.cs +++ b/Src/SourceGrid/Common/CustomScrollControl.cs @@ -696,11 +696,11 @@ public virtual void CustomScrollPageLeft() if (HScrollBarVisible) mHScrollBar.Value = Math.Max(mHScrollBar.Value - mHScrollBar.LargeChange, mHScrollBar.Minimum); } - public virtual void CustomScrollWheel(int rotationDelta) + public virtual void CustomScrollWheel(int rotationDelta, bool asVertical) { if (rotationDelta >= 120 || rotationDelta <= -120) { - if (VScrollBarVisible) + if (asVertical && VScrollBarVisible) { Point current = CustomScrollPosition; int newY = current.Y + @@ -714,6 +714,20 @@ public virtual void CustomScrollWheel(int rotationDelta) CustomScrollPosition = new Point(current.X, newY); } + else if (!asVertical && HScrollBarVisible) + { + Point current = CustomScrollPosition; + int newX = current.X + + SystemInformation.MouseWheelScrollLines * HScrollBar.SmallChange * -Math.Sign(rotationDelta); + + //check that the value is between max and min + if (newX < 0) + newX = 0; + if (newX > MaximumHScroll) + newX = MaximumHScroll; + + CustomScrollPosition = new Point(newX, current.Y); + } } } diff --git a/Src/SourceGrid/Grids/GridVirtual.cs b/Src/SourceGrid/Grids/GridVirtual.cs index c7c83ef..af29353 100644 --- a/Src/SourceGrid/Grids/GridVirtual.cs +++ b/Src/SourceGrid/Grids/GridVirtual.cs @@ -2101,7 +2101,54 @@ protected override void OnMouseWheel(MouseEventArgs e) { base.OnMouseWheel(e); - CustomScrollWheel(e.Delta); + // Check if shift key is being held down to simulate horizontal scroll + bool asVertical = (Control.ModifierKeys & Keys.Shift) != Keys.Shift; + + CustomScrollWheel(e.Delta, asVertical); + } + + protected virtual void OnMouseHWheel(MouseEventArgs e) + { + // Invert delta to match handling and scroll direction in Excel + CustomScrollWheel(-1 * e.Delta, false); + } + + private static class NativeMethods + { + internal static int SignedHIWORD(IntPtr ptr) + { + unchecked + { + int n = (int)(long)ptr; + return (short)((n >> 16) & (int)ushort.MaxValue); + } + } + + internal static int SignedLOWORD(IntPtr ptr) + { + unchecked + { + int n = (int)(long)ptr; + return (short)(n & (int)ushort.MaxValue); + } + } + } + + protected override void WndProc(ref Message m) + { + const int WM_MOUSEHWHEEL = 0x020E; + if (m.Msg == WM_MOUSEHWHEEL) + { + Point p = new Point(NativeMethods.SignedLOWORD(m.LParam), NativeMethods.SignedHIWORD(m.LParam)); + p = PointToClient(p); + OnMouseHWheel(new MouseEventArgs(MouseButtons.None, 0, p.X, p.Y, NativeMethods.SignedHIWORD(m.WParam))); + + // Set as handled and do not call base method (same as Control.WmMouseWheel) + m.Result = (IntPtr)1; + return; + } + + base.WndProc(ref m); } #endregion