如何从 IntPtr 句柄创建 WPF 游标

How to create a WPF Cursor from an IntPtr handle

假设我有一个游标句柄并且我想使用该句柄创建一个 WPF Cursor 实例。

在 Windows 表单中,System.Windows.Forms.Cursor class has a constructor which accepts IntPtr, but WPF System.Windows.Input.Cursor 没有接受 IntPtr 的构造函数。知道如何解决这个问题并从 IntPtr 句柄创建 WPF 游标吗?

例如,以下代码(从 借用)在 Windows 表单中有效,但我想在 WPF 中编写等效代码:

[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string dllToLoad);

[DllImport("user32.dll")]
private static extern IntPtr LoadCursor(IntPtr hInstance, UInt16 lpCursorName);

private void button1_Click(object sender, EventArgs e)
{
    var l = LoadLibrary("ole32.dll");
    var h = LoadCursor(l, 6);
    this.Cursor = new Cursor(h);
}

你需要使用CursorInteropHelper.Create(SafeHandle) which accepts a SafeHandle,那么你可以这样使用:

CursorInteropHelper.Create(theSafeHandle);

因此您需要使用 IntPtr 创建 SafeHandle 的实例。但是,现在的问题是 SafeHandle class 是抽象的!由于 Microsoft.Win32.SafeHandles namespace for cursor handle, you can create one by deriving from SafeHandleZeroOrMinusOneIsInvalid class:

中没有可用的实现
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
public sealed class SafeCursorHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    [DllImport("user32.dll")]
    private static extern bool DestroyCursor(IntPtr handle);

    public SafeCursorHandle() : base(true) { }
    public SafeCursorHandle(IntPtr handle) : base(true)
    {
        SetHandle(handle);
    }
    protected override bool ReleaseHandle()
    {
        return DestroyCursor(handle);
    }
}

最后,将所有内容放入 WPF 示例中,该示例与 Windows 表单示例做同样的事情:

//using System;
//using System.Runtime.InteropServices;
//using System.Windows;
//using System.Windows.Interop;

[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string dllToLoad);

[DllImport("user32.dll")]
private static extern IntPtr LoadCursor(IntPtr hInstance, UInt16 lpCursorName);

private void Button_Click(object sender, RoutedEventArgs e)
{
    var l = LoadLibrary("ole32.dll");
    var h = LoadCursor(l, 6);
    this.Cursor = CursorInteropHelper.Create(new SafeCursorHandle(h));
}