Unity调用SetWindowLong实现鼠标穿透,但是无法取消。

SetWindowLong(_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW);
用这条代码使鼠标可以穿过窗体,直接点击桌面,但是没有办法取消鼠标穿透。

望采纳!!!之前我写过一个

using System.Runtime.InteropServices;
 
public static class MousePenetration
{
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
 
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
 
    [DllImport("user32.dll")]
    private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
 
    private const int GWL_EXSTYLE = -20;
    private const int WS_EX_LAYERED = 0x80000;
    private const int WS_EX_TRANSPARENT = 0x20;
    private const int LWA_ALPHA = 0x2;
 
    public static void EnableMousePenetration(IntPtr windowHandle)
    {
        SetWindowLong(windowHandle, GWL_EXSTYLE, GetWindowLong(windowHandle, GWL_EXSTYLE) | WS_EX_LAYERED);
        SetLayeredWindowAttributes(windowHandle, 0, 0, LWA_ALPHA);
    }
 
    public static void DisableMousePenetration(IntPtr windowHandle)
    {
        SetWindowLong(windowHandle, GWL_EXSTYLE, GetWindowLong(windowHandle, GWL_EXSTYLE) & ~WS_EX_LAYERED);
    }
}

然后,你就可以在 Unity 脚本中调用这个类的 EnableMousePenetration 函数来启用鼠标穿透,调用 DisableMousePenetration 函数来禁用鼠标穿透
比如在我这里写的

void Start()
{
MousePenetration.EnableMousePenetration(gameObject.GetComponent().GetNativeWindowPtr());
}

Start 函数中调用 EnableMousePenetration 函数

参考下这个实例思路:C# 鼠标穿透窗体与恢复,链接:https://www.bbsmax.com/A/pRdBkDE2zn/

如果希望取消鼠标穿透可以使用以下代码:

SetWindowLong(_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED);

在这段代码中,去掉了 WS_EX_TRANSPARENT 和 WS_EX_TOOLWINDOW 风格。这两种风格都会导致窗口具有鼠标穿透功能。

需要注意的是,在使用 SetWindowLong 函数时,应该根据实际情况确定风格值。例如如果希望窗口保持在其他窗口之上,应使用 WS_EX_TOPMOST 风格。如果希望使用透明效果,应使用 WS_EX_LAYERED 风格。

另外,需要注意的是,在使用 SetWindowLong 函数时,应该将窗口的句柄作为第一个参数,将要更改的窗口风格标识符作为第二个参数,将新的风格值作为第三个参数。

最后,需要调用 SetWindowPos 函数来更新窗口的位置和大小。例如:

SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

这条代码并没有提供取消鼠标穿透的方法。如果想要取消鼠标穿透,你可以将窗口的扩展样式设置为不包含 WS_EX_TRANSPARENT 的样式,这样就可以解除鼠标穿透效果了。