如何从 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));
}
假设我有一个游标句柄并且我想使用该句柄创建一个 WPF Cursor 实例。
在 Windows 表单中,System.Windows.Forms.Cursor class has a constructor which accepts IntPtr, but WPF System.Windows.Input.Cursor 没有接受 IntPtr 的构造函数。知道如何解决这个问题并从 IntPtr 句柄创建 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));
}