Pinvoke 如何将类游标设置为null?

Pinvoke 如何将类游标设置为null?,pinvoke,wndproc,mouse-cursor,Pinvoke,Wndproc,Mouse Cursor,很抱歉发了这么长的帖子!恐怕我要解释一下。。。我有一个应用程序(在Unity3d中,但适用于windows)不使用WinForms,因此我不能使用作为System.windows.Forms命名空间一部分的游标类。但同样,我希望能够设置光标的当前形状 经过大量研究和谷歌搜索,我发现在user32.dll中使用p/Invoke调用某些方法是可能的。我是通过以下方式(某种程度上)实现的: 使用以下命令查找窗口的句柄: [DllImport("user32.dll")] public

很抱歉发了这么长的帖子!恐怕我要解释一下。。。我有一个应用程序(在Unity3d中,但适用于windows)不使用WinForms,因此我不能使用作为System.windows.Forms命名空间一部分的游标类。但同样,我希望能够设置光标的当前形状

经过大量研究和谷歌搜索,我发现在user32.dll中使用p/Invoke调用某些方法是可能的。我是通过以下方式(某种程度上)实现的:

使用以下命令查找窗口的句柄:

    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
并为类名提供null,为windowname提供窗口标题。然后使用返回的IntPtr调用:

    [DllImport("user32.dll")]
    public static extern IntPtr SetClassLong(IntPtr hwnd, int index, IntPtr dwNewLong);
并为索引提供“-4”,以便将指针指向处理所有低级别窗口消息的WindowProc,然后使用:

System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate()
生成指向我在托管代码中实现的新WndProc委托的本机指针。其签名如下:

    public long WndProc(IntPtr hwnd, uint msg, uint wparam, int lparam);
总之,我基本上是用托管回调重写本机窗口过程,然后处理所有窗口消息就成了我的责任。但是我对重写标准窗口过程的整个实现不感兴趣,我只是希望能够控制当光标在窗口上时它绘制鼠标光标形状的方式。因此,为此,我可以使用以下函数调用默认窗口进程:

    [DllImport("user32.dll")]
    public static extern long DefWindowProc(IntPtr hwnd, uint msg, uint wparam, int lparam);
然后立即使用以下命令将光标设置到其他位置:

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    private static extern IntPtr SetCursor(IntPtr hCursor);
这类作品。:)我说“sort of”,因为我看到了一些闪烁,因为默认的windowproc首先将游标设置为类游标,然后紧接着,我的实现使用SetCursor将其设置为我想要的自定义游标。可以通过将类游标设置为null来纠正这种情况。这样做会导致系统不绘制光标,并期望应用程序为每个窗口消息设置光标,而这正是我正在做的,因此它将阻止他们为谁可以设置光标而争吵,并消除闪烁。这记录在MSDN上,网址为:

它们解释了必须将类游标设置为null。但这正是我的知识不足之处(类游标设置为SetClassLong,如上文所述


但是游标的新值的数据类型是IntPtr。此数据类型不可为null,如果传入null,编译器会抱怨,传入IntPtr.zero不起作用。那么我该如何完成文章建议的内容呢?如何使用p/Invoke将类游标设置为null?

好吧,你做得不对。只有当你允许为WM_SETCURSOR消息调用原始WndProc。您的声明也非常错误。从Winforms NativeWindow类派生以使其正确,AssignHandle()方法将窗口子类化。当您看到WM_DESTROY消息时,重写WndProc.ReleaseHandle。我理解,并感谢您的评论。:)但我不能按照您的指示操作,因为正如我指出的,这是一个Unity3D应用程序,其运行时隐藏了创建窗口的代码。我无法控制进行渲染的窗口的来源,并且我没有访问System.Windows.Forms命名空间的权限。我可以重写窗口的WndProc,并在我被重写的WndProc收到WM_SetCursor消息时调用我自己的SetCursor函数,然后在消息是其他消息时调用原始窗口过程。听起来不错。你只需要把手,你已经拿到了。添加对System.Windows.Forms的引用永远不会是问题。好的。。。显然,关于P/Invoke有很多事情我还没有完全理解。但我才刚刚开始使用它我能否说服您向我展示如何使用代码示例正确地对本机窗口进行子类化,或者提供带有演示的链接?