Windows Forms:如何通过部分透明的总在最前窗口传递点击事件

17

我正在设计一个窗口,它始终在屏幕上,并且大约20%不透明度。 它旨在成为一种状态窗口,因此它始终在最上层,但我希望人们能够通过窗口点击到下面的任何其他应用程序。这是一个不透明的窗口,我正在打字时它在这个SO帖子的顶部:

Example

看到那个灰色条了吗? 它会阻止我在标签框中输入内容。


1
无法使用WinForms实现。 - rory.ap
1
你有证据支持那个答案吗?我觉得很难相信... - Sam Weaver
1
相信它。我的“证据”是使用Win Forms十多年的经验。 - rory.ap
2
@rory.ap 我认为已经发布的答案就是 OP 在寻找的内容。我漏掉了问题的某些部分吗?它在 Windows 7 上工作正常。 - Reza Aghaei
3
我纠正了。那很酷! - rory.ap
1个回答

34

您可以通过添加 WS_EX_LAYEREDWS_EX_TRANSPARENT 样式来使窗口具有“点击穿透”功能。此外,要将其始终置于顶层,请将其 TopMost 设置为 true,并使用合适的 Opacity 值来使其半透明:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.Opacity = 0.5;
        this.TopMost = true;
    }
    [DllImport("user32.dll", SetLastError = true)]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    const int GWL_EXSTYLE = -20;
    const int WS_EX_LAYERED = 0x80000;
    const int WS_EX_TRANSPARENT = 0x20;
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        var style = GetWindowLong(this.Handle, GWL_EXSTYLE);
        SetWindowLong(this.Handle,GWL_EXSTYLE , style | WS_EX_LAYERED | WS_EX_TRANSPARENT);
    }
}

样例结果

输入图像描述


2
你可以重写CreateParams并使用P/Invoke设置ExStyle。 - TnTinMn
我尝试了这个解决方案,但当我点击窗口时什么也没有发生。 - BruceOverflow
我使用带有Mono的Ubuntu,似乎这不起作用... - BruceOverflow
@BruceStackOverFlow 这是在 Windows 上的 WinForms (.NET),而不是在 Linux 上的 Mono。 - Reza Aghaei
是的,但Mono完全支持Windows Form 2.0,这在某种程度上可以工作,例如像发布的gif一样,但点击无法工作... - BruceOverflow
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接