最透明的可点击通过窗体和可点击通过控件C#

本文关键字:控件 透明 窗体 | 更新日期: 2023-09-27 18:29:37

我在透明表单上使用GDI绘制了一些矩形。

表单是全屏的,并且总是在顶部。此外,还可以使用以下方法进行点击:最上面的形式,点击";通过";可能的

然而,绘制的矩形无法像我的表单一样点击通过,每次我点击它们时,我的应用程序都会失去焦点。当我把鼠标悬停在它们上面时,我可以看到我的应用程序光标(表单下的窗口是一个游戏,所以它有一个自定义光标)。

你能告诉我如何使所有控件都不可聚焦和点击吗?这可能吗?或者我必须使用DirectX绘图之类的东西?

我搜索了整个网络和stackoverflow,使用了各种解决方案,但都没有成功。

谢谢。

最透明的可点击通过窗体和可点击通过控件C#

我不确定我是否完全理解您想要实现的目标,但是,如果您希望制作一个可以接收鼠标点击但不会"窃取"焦点的控件,这是很有可能的:

public class Box : Control
{
    public Box()
    {
        // Prevent mouse clicks from 'stealing' focus:
        TabStop = false;
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        DrawText(e.Graphics);
    }
    // Display control text so we know what the button does:
    private void DrawText(Graphics graphics)
    {
        using (var brush = new SolidBrush(this.ForeColor))
        {
            graphics.DrawString(
                this.Text, this.Font, brush,
                new PointF()
                {
                    X = ((float)this.Width / 2f),
                    Y = (((float)this.Height / 2f) - (this.Font.GetHeight(graphics) / 2f))
                },
                new StringFormat()
                {
                    Alignment = StringAlignment.Center
                });
        }
    }
}


这个简单的控件将显示为一个矩形,它仍然能够接收鼠标点击和激发点击事件,但不会从表单上的其他控件(也不会从表单本身)窃取焦点。


将窗体上的透明键设置为其背景色将使窗体的其余部分不可见,从而只有矩形"按钮"可见。这也可以与Opacity属性相结合,使显示的内容成为半透明的,但不透明度恰好为零的窗体将不会与鼠标交互(根据Windows设计)。


简单地将窗体的TopMost属性设置为true可能不足以使该窗口位于所有其他窗口之上。首次创建表单时,您可能需要从表单中进行以下API调用(例如、放置在构造函数中、OnLoad事件、):

SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW));


有关此函数的MSDN文档可以在此处找到。

为了进行此调用,您需要将以下Windows API声明添加到表单类:

[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

并添加以下常量:

private const int SWP_NOMOVE     = 0x0002;
private const int SWP_NOSIZE     = 0x0001;
private const int SWP_SHOWWINDOW = 0x0040;
private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);


我希望这能有所帮助!