How to draw on top of the right-click menu in .NET/C#?

两盒软妹~` 提交于 2019-12-12 10:49:44

问题


I'm developing an assistive technology application (in C#) that overlays information on top of the currently open window. It detects clickable elements, and labels them.

To do this, I'm currently creating a borderless, transparent window with TopMost set to "true", and drawing the labels on that. This means there is always a window hovering in front of the current application, on which I can draw the labels.

The problem is, this window doesn't cover the right-click menu - only other windows. When the user right-clicks, the context menu is drawn above the overlay.

I need to be able to label elements in the right-click menu, but I can't draw on top of it with the current implementation. Does anybody know of a solution?

Edit: This is the relevant code for drawing the overlay. I've set the form options in the form designer, not in the code explicity, so I'm not sure how much it will help. I've removed the code not related to drawing, or the form itself:

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);
        }
    }    
}

回答1:


I've found a bit of a hack solution.

By periodically bringing the overlay window to the front, I can bring it to the top of the Z-order where it covers the right-click menu. It's not perfect, but it does work. This is the core concept, with multithreading stripped out:

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);
        }
    }
}

(This assumes "OverlayForm" is a form with the relevant flags set in the form designer - i.e. "Always on Top," "Transparency Key," "Borderless," "Maximised," etc.)

I've only tested this on Windows 8.1. I don't know if the Z-order behaves this way on other versions.




回答2:


Add a contextmenu to your form and then assign it in the control's properties under ContextMenuStrip.

ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Item 1");
cm.MenuItems.Add("Item 2");

pictureBox1.ContextMenu = cm;


来源:https://stackoverflow.com/questions/37395368/how-to-draw-on-top-of-the-right-click-menu-in-net-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!