1

I'm trying to learn a few things, but I'm kinda stuck and I don't know where to go from here. I'm either blind or just confused.

I've been looking at some scripts from here: Answers.Unity

Right now, I got the background transparency working on my main screen, but I'm wondering what I should do to make this happen on my second monitor too. Or third, if I had one. As of right now the other screens turn black. This is the code:

[SerializeField]
private Material m_Material;

[SerializeField]
private Camera mainCamera;

private bool clickThrough = true;
private bool prevClickThrough = true;

private struct MARGINS
{
    public int cxLeftWidth;
    public int cxRightWidth;
    public int cyTopHeight;
    public int cyBottomHeight;
}

[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();

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

[DllImport("user32.dll")]
static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

[DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, byte bAlpha, int dwFlags);

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern int SetWindowPos(IntPtr hwnd, int hwndInsertAfter, int x, int y, int cx, int cy, int uFlags);

[DllImport("Dwmapi.dll")]
private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);

const int GWL_STYLE = -16;
const uint WS_POPUP = 0x80000000;
const uint WS_VISIBLE = 0x10000000;
const int HWND_TOPMOST = -1;

int fWidth;
int fHeight;
IntPtr hwnd;
MARGINS margins;

public bool OverUI()
{ //Use sparingly
  //Set up the new Pointer Event
    PointerEventData m_PointerEventData = new PointerEventData(EventSystem.current);
    m_PointerEventData.position = Input.mousePosition;
    List<RaycastResult> results = new List<RaycastResult>();
    EventSystem.current.RaycastAll(m_PointerEventData, results);
    if (results.Count > 0) return true;
    return false;
}

void Start()
{

        fWidth = Screen.width;
        fHeight = Screen.height;
        margins = new MARGINS() { cxLeftWidth = -1 };
        hwnd = GetActiveWindow();

        SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
        SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
        DwmExtendFrameIntoClientArea(hwnd, ref margins);

        Application.runInBackground = true;
}

void Update()
{
    // If our mouse is overlapping an object
    RaycastHit hit = new RaycastHit();
    clickThrough = !Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition).origin,
            mainCamera.ScreenPointToRay(Input.mousePosition).direction, out hit, 100,
            Physics.DefaultRaycastLayers) && !OverUI();

    if (clickThrough != prevClickThrough)
    {
        if (clickThrough)
        {
                SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
                SetWindowLong (hwnd, -20, (uint)524288 | (uint)32);//GWL_EXSTYLE=-20; WS_EX_LAYERED=524288=&h80000, WS_EX_TRANSPARENT=32=0x00000020L
                SetLayeredWindowAttributes (hwnd, 0, 255, 2);// Transparency=51=20%, LWA_ALPHA=2
                SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
        }
        else
        {
                SetWindowLong (hwnd, -20, ~(((uint)524288) | ((uint)32)));//GWL_EXSTYLE=-20; WS_EX_LAYERED=524288=&h80000, WS_EX_TRANSPARENT=32=0x00000020L
                SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
        }
        prevClickThrough = clickThrough;
    }
}

void OnRenderImage(RenderTexture from, RenderTexture to)
{
    Graphics.Blit(from, to, m_Material);
}

Could anyone guide me a little bit so that I can figure this out?

Edit: I've figured out a little bit.. I think. When Unity opens, (with multiple displays), it creates two windows in the task bar. I'm guessing I need to find that other window, set it as active and then run something similar to this code again. But I'm guessing I would need to fix the pos and margins before doing so. It's beyond my understanding of WinApi right now, but I hope someone knows a bit more about this than me.

Epicei
  • 11
  • 3

0 Answers0