如何从 IntPtr 句柄创建 WPF 光标 [重复]

Posted

技术标签:

【中文标题】如何从 IntPtr 句柄创建 WPF 光标 [重复]【英文标题】:How to create a WPF Cursor from an IntPtr handle [duplicate] 【发布时间】:2021-11-21 20:10:04 【问题描述】:

假设我有一个光标句柄,我想使用该句柄创建一个 WPF 光标实例。

在 Windows 窗体中,System.Windows.Forms.Cursor 类具有接受 IntPtr 的构造函数,但 WPF System.Windows.Input.Cursor 没有接受 IntPtr 的构造函数。知道如何解决这个问题并从 IntPtr 句柄创建 WPF 光标吗?

例如,以下代码(借用自 this post)在 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);

【问题讨论】:

这篇文章的灵感来自于 cmets here 中提出的一个问题。 【参考方案1】:

你需要使用接受SafeHandle的CursorInteropHelper.Create(SafeHandle),然后你可以这样使用它:

CursorInteropHelper.Create(theSafeHandle);

因此,您需要使用IntPtr 创建SafeHandle 的实例。但是,现在的问题是 SafeHandle 类是抽象的!由于Microsoft.Win32.SafeHandles namespace 中没有可用于光标句柄的实现,您可以通过从SafeHandleZeroOrMinusOneIsInvalid 类派生来创建一个:

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));

【讨论】:

以上是关于如何从 IntPtr 句柄创建 WPF 光标 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

给定 IntPtr 句柄,更改 Window 背景颜色

C# 句柄指针的 JFrame 等效项

IntPtr

初识IntPtr

wpf window窗口中嵌入一个window窗口

从 IntPtr 创建 NSException