如何在 WPF 应用程序中使用来自 ole32.dll 的 Cursor?

How do you use a Cursor from ole32.dll in a WPF application?

我想使用 Windows 中未包含在 'Cursors' class 中的内置游标之一。我发现 的答案似乎提供了我需要的信息,但是有问题。 System.Windows.Input.Cursor 没有接受 IntPtr 的构造函数。这是该答案提供的代码片段(评论是我的):

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

[DllImport("user32.dll")]
public 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);//this does not compile!
}

我的问题是:如何从 ole32.dll 中包含的游标之一创建 System.Windows.Input.Cursor

我用 this question 的答案弄明白了。

这是我的代码:

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

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

    public static Cursor GetCursor(ushort cursorNumber)
    {
        var library = LoadLibrary("ole32.dll");
        var cursorPointer = LoadCursor(library, cursorNumber);
        return CursorInteropHelper.Create(new SafeCursorHandle(cursorPointer));
    }

    class SafeCursorHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
    {
        public SafeCursorHandle(IntPtr handle) : base(true)
        {
            base.SetHandle(handle);
        }
        protected override bool ReleaseHandle()
        {
            if (!this.IsInvalid)
            {
                if (!DestroyCursor(this.handle))
                    throw new System.ComponentModel.Win32Exception();
                this.handle = IntPtr.Zero;
            }
            return true;
        }
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool DestroyCursor(IntPtr handle);
    }
}

用法:

var cursor = WindowsCursors.GetCursor(3);