Windows Forms: Pass clicks through a partially transparent always-on-top window
Asked Answered
M

1

17

I am designing a window that is always on screen and around 20% opaque. It is designed to be a sort of status window, so it is always on top, but I want people to be able to click through the window to any other application below. Here's the opaque window sitting on top of this SO post as I type right now:

Example

See that grey bar? It would prevent me from typing in the tags box at the moment.

Manure answered 4/10, 2016 at 15:2 Comment(5)
Not possible with winforms.Liner
Do you have any evidence to back up that answer? I find that hard to believe...Manure
Believe it. My "evidence" is over a decade of experience using win forms.Liner
@Liner I think the posted answer is what the OP is looking for. Am I missing some part of the question? It's working on Windows 7.Headstrong
I stand corrected. That's pretty cool!Liner
H
33

You can make a window, click-through by adding WS_EX_LAYERED and WS_EX_TRANSPARENT styles to its extended styles. Also to make it always on top set its TopMost to true and to make it semi-transparent use suitable Opacity value:

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

Sample Result

enter image description here

Headstrong answered 4/10, 2016 at 15:18 Comment(7)
You could just override CreateParams and set the ExStyle instead using P/Invoke.Clo
I tried this solution but when I click through the window happens nothingAntimasque
@BruceStackOverFlow Click will pass to the background window.Headstrong
I use ubuntu with mono seems that this not working... #61000580Antimasque
@BruceStackOverFlow It's WinForms (.NET) on Windows not mono on Linux.Headstrong
Ya but mono support completely windows form 2.0, this work in part, for example, like as the posted gif but the click non work....Antimasque
@BruceStackOverFlow The part which is not working is in fact the Windows API part :)Headstrong

© 2022 - 2024 — McMap. All rights reserved.