c# - 鼠标滚轮滚动工具条菜单项

标签 c# winforms scroll toolstripitem toolstripmenu

我有一些包含许多菜单项的菜单。鼠标滚轮不会滚动它们。我必须使用键盘箭头或单击顶部和底部的箭头。 是否可以使用鼠标滚轮滚动工具条菜单项? 谢谢

最佳答案

您可以使用此类在应用程序范围内启用它:

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<ToolStrip, int> ScrollInternal
        = (Action<ToolStrip, int>)Delegate.CreateDelegate(typeof(Action<ToolStrip, int>),
            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);
    }
}

关于c# - 鼠标滚轮滚动工具条菜单项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13139074/

相关文章:

c# - 我应该在 visual studio 中的 wwwroot 下创建文件上传文件夹吗?

c# - 绑定(bind)到列表的组合框。向列表中添加新项目不会影响组合框

user-interface - 平移,精确定义

.net - 在不使用大量内存的情况下显示大文件的最佳方法是什么?

c# - 应用程序似乎有两个 session cookie

c# - 使用 MVC 3 Entity Framework 代码优先,如何在一对多关系中创建一个新的 "many"对象?

c# - 为什么我分配给变量的值不见了?

winforms - 如何防止编译器为非本地化应用程序创建 appname.resources.dll?

html - 滚动文本 - 条目同时显示

c# - Ravendb mapreduce 按多个字段分组