SetWindowLong启用/禁用单击表单

时间:2014-09-09 11:53:05

标签: 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);
}

因此,这成功地呈现了我的应用程序“点击”,因此它可以保持最顶层,但我仍然可以点击它背后的应用程序。 用于它的流行代码,但我的问题是,如何禁用它?

如何还原它以便我可以再次单击我的应用程序而无需重新启动它?

1 个答案:

答案 0 :(得分:4)

wl = wl | 0x80000 | 0x20;

您在这里使用按位或添加标记WS_EX_LAYEREDWS_EX_TRANSPARENT。而对于它的价值,使用这样的魔法常量是不好的形式。使用适当的名称声明常量:

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

为方便起见,在uintGetWindowLong中使用SetWindowLong

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

然后设置扩展样式:

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

像这样反转这种变化:

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

你可以对样式使用枚举,但这对我来说似乎有些偏差,因为值与按位运算相结合。因此,我更喜欢使用uint