【问题标题】:How do I create drop lines while dragging a menu item on a WinForm?如何在 WinForm 上拖动菜单项时创建下拉线?
【发布时间】:2010-04-15 01:52:59
【问题描述】:

我想模仿 Google Chrome/FireFox 的功能,例如,在重新排列书签时,当您拖动菜单项时,它会在建议的放置点处创建一条黑线,如下所示:

alt text http://www.freeimagehosting.net/uploads/977900a13a.jpg

我已经实现了拖放功能来重新排列菜单,但我想添加这些分隔线作为附加功能。

有没有办法在 .NET Framework (3.5) 中做到这一点,还是我必须求助于 Win32 api 调用?只是想在我走那条路之前问一下。

【问题讨论】:

  • 认为这就是您要问的问题 - 如果不是,请随时回滚。
  • @Bryan:您不需要将语言放在标题中,因为它在标签中。

标签: c# menu menuitem


【解决方案1】:

在纯 .NET 代码中执行此操作的一种常见方法是创建一个无边框的表单,该表单的颜色和大小看起来像落点线。还要在此表单上将 TopMost 属性设置为 True。

然后使用 MouseDown/MouseUp/MouseMove 事件来确定何时何地显示下拉线以响应用户操作。

要正确定位放置线表单,您需要查看 Control.PointToScreen 和/或 Control.RectangleToScreen(可能还有 Control.PointToClient)方法。

【讨论】:

    【解决方案2】:

    我认为最简单的方法是获取您正在拖动的弹出菜单的句柄。获得句柄后,您可以使用Graphics 对象直接在其上绘制。

    获取句柄可能需要一些 API 魔力。我正在查。

    更新:没有太多魔力,尽管有一个讽刺意味(见下文)。为此,请添加

    using System.Runtime.InteropServices;
    

    在您的表单或班级或其他任何内容的顶部。在某处添加此声明:

    [DllImport("user32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindowA(string lpClassName, 
        string lpWindowName);
    

    弹出式菜单窗口(即您通常看不到的部分)是类名为“#32768”的最顶层窗口。这段代码展示了如何获取菜单的窗口句柄并直接在上面绘制:

    IntPtr hWnd = FindWindowA("#32768", null);
    if (hWnd != IntPtr.Zero)
    {
        using (Graphics g = Graphics.FromHwnd(hWnd))
        { 
            g.FillRectangle(Brushes.Red,
                new Rectangle(0, 0, 20, 20));
        }
    }
    

    此示例仅在菜单的左上角绘制了一个 20x20 的红色方块。要渲染下降线,你必须做更多的工作来确定它应该在哪里,然后在那里绘制你想要的任何东西。在我看来,它只是一条两像素高的黑线,两端各有小部分箭头,所以应该不难模仿。

    你可能不得不担心清理你画的任何东西,但我对此表示怀疑。弹出菜单窗口是临时的,我认为当您将光标移到它们上方时它们会自动重新绘制。如果没有,您可能必须在每次下拉线更改位置时向弹出菜单窗口发送重绘消息。

    即使您打开了多个嵌套菜单(它们都可能具有类名“#32768”),它似乎也可以工作 - FindWindow 似乎总是返回 z 顺序中最顶部的菜单。另一件好事 - 因为您是在菜单窗口本身上绘图,所以该行将位于半透明放置光标下方,这就是您想要的。

    具有讽刺意味的是:我在一堆不同的程序和菜单上对此进行了测试。它适用于所有这些和所有菜单,除了 Internet Explorer 中的收藏夹菜单。我猜那个特定的菜单使用的不是内置的 Windows 菜单。如果您使用常规 .Net 菜单执行此操作,它应该可以正常工作。

    【讨论】:

      猜你喜欢
      • 2013-09-22
      • 2014-11-14
      • 1970-01-01
      • 1970-01-01
      • 2023-01-30
      • 2017-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多