.NET/C#中如何在右键菜单上方绘制?
How to draw on top of the right-click menu in .NET/C#?
我正在开发一个辅助技术应用程序(在 C# 中),它将信息叠加在当前打开的 window 之上。它检测可点击的元素,并标记它们。
为此,我目前正在创建一个无边界、透明的 window,并将 TopMost 设置为 "true",并在其上绘制标签。这意味着总是有一个 window 悬停在当前应用程序的前面,我可以在上面绘制标签。
问题是,这个 window 不包括右键单击菜单 - 只有其他 windows。当用户单击鼠标右键时,上下文菜单绘制在叠加层上方。
我需要能够在右键单击菜单中标记元素,但我无法使用当前实现在其上绘制。有人知道解决方案吗?
编辑:这是绘制叠加层的相关代码。我在表单设计器中设置了表单选项,而不是在代码中明确设置,所以我不确定它会有多大帮助。我删除了与绘图无关的代码,或表单本身:
public partial class OverlayForm : Form
{
public OverlayForm()
{
}
protected override void OnPaint(PaintEventArgs eventArgs)
{
base.OnPaint(eventArgs);
Graphics graphics = eventArgs.Graphics;
Brush brush = new SolidBrush(this.labelColor);
foreach (ClickableElement element in this.elements)
{
Region currentRegion = element.region;
graphics.FillRegion(brush, currentRegion);
}
}
}
我找到了一些 hack 解决方案。
通过定期将叠加层 window 置于最前面,我可以将其置于 Z 顺序的顶部,覆盖右键单击菜单。它并不完美,但确实有效。这是核心概念,去掉了多线程:
public class OverlayManager
{
OverlayForm overlay;
public OverlayManager()
{
this.overlay = new OverlayForm();
this.overlay.Show();
this.RepeatedlyBringToFront();
}
private void RepeatedlyBringToFront()
{
while (true)
{
this.overlay.BringToFront();
Thread.Sleep(50);
}
}
}
(假设 "OverlayForm" 是一个在表单设计器中设置了相关标志的表单 - 即 "Always on Top," "Transparency Key," "Borderless," "Maximised," 等)
我只在 Windows 8.1 上测试过。我不知道 Z 顺序在其他版本上是否以这种方式表现。
向表单添加上下文菜单,然后在 ContextMenuStrip 下的控件属性中分配它。
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Item 1");
cm.MenuItems.Add("Item 2");
pictureBox1.ContextMenu = cm;
我正在开发一个辅助技术应用程序(在 C# 中),它将信息叠加在当前打开的 window 之上。它检测可点击的元素,并标记它们。
为此,我目前正在创建一个无边界、透明的 window,并将 TopMost 设置为 "true",并在其上绘制标签。这意味着总是有一个 window 悬停在当前应用程序的前面,我可以在上面绘制标签。
问题是,这个 window 不包括右键单击菜单 - 只有其他 windows。当用户单击鼠标右键时,上下文菜单绘制在叠加层上方。
我需要能够在右键单击菜单中标记元素,但我无法使用当前实现在其上绘制。有人知道解决方案吗?
编辑:这是绘制叠加层的相关代码。我在表单设计器中设置了表单选项,而不是在代码中明确设置,所以我不确定它会有多大帮助。我删除了与绘图无关的代码,或表单本身:
public partial class OverlayForm : Form
{
public OverlayForm()
{
}
protected override void OnPaint(PaintEventArgs eventArgs)
{
base.OnPaint(eventArgs);
Graphics graphics = eventArgs.Graphics;
Brush brush = new SolidBrush(this.labelColor);
foreach (ClickableElement element in this.elements)
{
Region currentRegion = element.region;
graphics.FillRegion(brush, currentRegion);
}
}
}
我找到了一些 hack 解决方案。
通过定期将叠加层 window 置于最前面,我可以将其置于 Z 顺序的顶部,覆盖右键单击菜单。它并不完美,但确实有效。这是核心概念,去掉了多线程:
public class OverlayManager
{
OverlayForm overlay;
public OverlayManager()
{
this.overlay = new OverlayForm();
this.overlay.Show();
this.RepeatedlyBringToFront();
}
private void RepeatedlyBringToFront()
{
while (true)
{
this.overlay.BringToFront();
Thread.Sleep(50);
}
}
}
(假设 "OverlayForm" 是一个在表单设计器中设置了相关标志的表单 - 即 "Always on Top," "Transparency Key," "Borderless," "Maximised," 等)
我只在 Windows 8.1 上测试过。我不知道 Z 顺序在其他版本上是否以这种方式表现。
向表单添加上下文菜单,然后在 ContextMenuStrip 下的控件属性中分配它。
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Item 1");
cm.MenuItems.Add("Item 2");
pictureBox1.ContextMenu = cm;