Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SetWindowLong Enable/Disable Click through form

Tags:

c#

.net

public enum GWL
    {
        ExStyle = -20
    }

    public enum WS_EX
    {
        Transparent = 0x20,
        Layered = 0x80000
    }

    public enum LWA
    {
        ColorKey = 0x1,
        Alpha = 0x2
    }

    [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
    public static extern int GetWindowLong(IntPtr hWnd, GWL nIndex);

    [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
    public static extern int SetWindowLong(IntPtr hWnd, GWL nIndex, int dwNewLong);

    [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
    public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte alpha, LWA dwFlags);

void ClickThrough()
{
int wl = GetWindowLong(this.Handle, GWL.ExStyle);
                wl = wl | 0x80000 | 0x20;
                SetWindowLong(this.Handle, GWL.ExStyle, wl);
}

So this successfully renders my application "Click-through", so it can stay Topmost but I can still click on applications that are behind it. Popular piece of code used for it, but my question is, how do I disable it?

How do I revert it so I can once again click on my application without restarting it?

like image 460
Zute Avatar asked Dec 01 '25 07:12

Zute


1 Answers

wl = wl | 0x80000 | 0x20;

Here you are using bitwise or to add in the flags WS_EX_LAYERED and WS_EX_TRANSPARENT. And for what it is worth, it is poor form to use magic constants like that. Declare constants with the appropriate names:

public const uint WS_EX_LAYERED = 0x00080000;
public const uint WS_EX_TRANSPARENT = 0x00000020;

And use uint in GetWindowLong and SetWindowLong, for convenience.

[DllImport("user32.dll")]
public static extern uint GetWindowLong(IntPtr hWnd, GWL nIndex);

[DllImport("user32.dll")]
public static extern uint SetWindowLong(IntPtr hWnd, GWL nIndex, uint dwNewLong);

Then set the extended style like this:

uint ex_style = GetWindowLong(this.Handle, GWL.ExStyle);
SetWindowLong(this.Handle, GWL.ExStyle, ex_style | WS_EX_LAYERED | WS_EX_TRANSPARENT);

Reverse this change like so:

uint ex_style = GetWindowLong(this.Handle, GWL.ExStyle);
SetWindowLong(this.Handle, GWL.ExStyle, ex_style & !WS_EX_LAYERED & !WS_EX_TRANSPARENT);

You can use an enum for styles but that seems a little off to me since values are combined with bitwise operations. Hence I prefer to use uint.

like image 156
David Heffernan Avatar answered Dec 03 '25 21:12

David Heffernan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!