像鼠标光标一样的窗口

时间:2019-05-12 19:11:34

标签: c# windows winforms unity3d

我正在编程要在Windows 10上具有运动模糊的操作系统中使用的鼠标光标。之所以决定使用Unity3D,是因为Unity3D在效果和硬件渲染方面非常强大。我编码了一个叠加窗口以使其成为最顶层。但是,任何应用程序上的上下文菜单都将呈现在窗口顶部,而表单上的对象将位于上下文菜单后面。有没有办法做到这一点?我不需要为此使用Unity3D,因此欢迎提出任何建议。

这是我为窗口编写的代码。

using System;
using System.Runtime.InteropServices;
using UnityEngine;

[RequireComponent(typeof(Camera))]
public class TransparentWindow : MonoBehaviour
{
    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    }

    // Define function signatures to import from Windows APIs

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

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

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

    [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, uint uFlags);

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



    // Definitions of window styles
    const int GWL_STYLE = -16;
    const uint WS_POPUP = 0x80000000;
    const uint WS_VISIBLE = 0x10000000;
    const uint WS_EX_LAYERED = 0x00080000;
    const uint WS_EX_TRANSPARENT = 0x00000020;
    const uint WS_EX_TOPMOST = 0x00000008;

    const int HWND_TOPMOST = -1;



    const UInt32 SWP_NOSIZE = 0x0001;
    const UInt32 SWP_NOMOVE = 0x0002;
    const UInt32 SWP_NOZORDER = 0x0004;
    const UInt32 SWP_NOREDRAW = 0x0008;
    const UInt32 SWP_NOACTIVATE = 0x0010;
    const UInt32 SWP_FRAMECHANGED = 0x0020;
    const UInt32 SWP_SHOWWINDOW = 0x0040;
    const UInt32 SWP_HIDEWINDOW = 0x0080;
    const UInt32 SWP_NOCOPYBITS = 0x0100;
    const UInt32 SWP_NOOWNERZORDER = 0x0200;
    const UInt32 SWP_NOSENDCHANGING = 0x0400;
    const UInt32 SWP_DRAWFRAME = SWP_FRAMECHANGED;
    const UInt32 SWP_NOREPOSITION = SWP_NOOWNERZORDER;

    const UInt32 SWP_DEFERERASE = 0x2000;
    const UInt32 SWP_ASYNCWINDOWPOS = 0x4000;

    // This static method is required because legacy OSes do not support
    // SetWindowLongPtr 
    public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, uint dwNewLong)
    {
        if (IntPtr.Size == 8)
            return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
        else
            return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong));
    }

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

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

    void Start()
    {
#if !UNITY_EDITOR // You really don't want to enable this in the editor..

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


        SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
        SetWindowLongPtr(hwnd, -20, WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT); // GWL_EXSTYLE -20
        SetLayeredWindowAttributes(hwnd, 0, 255, 2);
        SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);

        DwmExtendFrameIntoClientArea(hwnd, ref margins);

#endif
    }

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

这是动画截图,显示了我的问题。请在此屏幕快照中看到第二个鼠标光标,该屏幕紧随操作系统的鼠标光标:

Example

0 个答案:

没有答案