我想模仿Google Chrome / FireFox的功能,例如,在重新排列书签时,当您拖动菜单项时,它会在建议的放置点处创建一条黑线,如下所示:
alt text http://www.freeimagehosting.net/uploads/977900a13a.jpg
我已经实现了拖放功能来重新排列菜单,但我想添加这些分隔线作为附加功能。
有没有办法在.NET Framework(3.5)中执行此操作,还是必须使用Win32 api调用?我想走之前就想问一下。
答案 0 :(得分:0)
在纯.NET代码中执行此操作的常用方法是创建一个无边框表单,其颜色和大小看起来像下拉点行。还要在此表单上将TopMost属性设置为True。
然后使用MouseDown / MouseUp / MouseMove事件确定显示下拉线的时间和位置以响应用户操作。
要正确定位下拉线表单,您需要查看Control.PointToScreen和/或Control.RectangleToScreen(以及可能的Control.PointToClient)方法。
答案 1 :(得分:0)
我认为最简单的方法是获取您拖动的弹出菜单的句柄。获得句柄后,可以使用Graphics
对象直接在其上绘制。
获取句柄可能需要一些API mojo。我正在查找。
更新:根本没有多少魔力,尽管有一个具有讽刺意味的问题(见下文)。为此,请添加
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菜单进行此操作,它应该可以正常工作。