Mouse wheel scrolling Toolstrip menu items

后端 未结 4 1368
梦如初夏
梦如初夏 2021-01-14 13:48

I have some menus that contain many menuitems. Mouse wheel doesn\'t scroll them. I have to use the keyboard arrows or click the arrows at top and bottom. Is it possible to u

4条回答
  •  孤街浪徒
    2021-01-14 14:04

    You can enable it application wide with this class:

    public class DropDownMenuScrollWheelHandler : System.Windows.Forms.IMessageFilter
    {
        private static DropDownMenuScrollWheelHandler Instance;
        public static void Enable(bool enabled)
        {
            if (enabled)
            {
                if (Instance == null)
                {
                    Instance = new DropDownMenuScrollWheelHandler();
                    Application.AddMessageFilter(Instance);
                }
            }
            else
            {
                if (Instance != null)
                {
                    Application.RemoveMessageFilter(Instance);
                    Instance = null;
                }
            }
        }
        private IntPtr activeHwnd;
        private ToolStripDropDown activeMenu;
    
        public bool PreFilterMessage(ref Message m)
        {
            if (m.Msg == 0x200 && activeHwnd != m.HWnd) // WM_MOUSEMOVE
            {
                activeHwnd = m.HWnd;
                this.activeMenu = Control.FromHandle(m.HWnd) as ToolStripDropDown;
            }
            else if (m.Msg == 0x20A && this.activeMenu != null) // WM_MOUSEWHEEL
            {
                int delta = (short)(ushort)(((uint)(ulong)m.WParam) >> 16);
                handleDelta(this.activeMenu, delta);
                return true;
            }
            return false;
        }
    
        private static readonly Action ScrollInternal
            = (Action)Delegate.CreateDelegate(typeof(Action),
                typeof(ToolStrip).GetMethod("ScrollInternal",
                    System.Reflection.BindingFlags.NonPublic
                    | System.Reflection.BindingFlags.Instance));
    
        private void handleDelta(ToolStripDropDown ts, int delta)
        {
            if (ts.Items.Count == 0)
                return;
            var firstItem = ts.Items[0];
            var lastItem = ts.Items[ts.Items.Count - 1];
            if (lastItem.Bounds.Bottom < ts.Height && firstItem.Bounds.Top > 0)
                return;
            delta = delta / -4;
            if (delta < 0 && firstItem.Bounds.Top - delta > 9)
            {
                delta = firstItem.Bounds.Top - 9;
            }
            else if (delta > 0 && delta > lastItem.Bounds.Bottom - ts.Height + 9)
            {
                delta = lastItem.Bounds.Bottom - owner.Height + 9;
            }
            if (delta != 0)
                ScrollInternal(ts, delta);
        }
    }
    

提交回复
热议问题