You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WPF应用中使用ole32.dll中的内置系统光标资源

WPF 加载系统内置自定义光标实现方案

问题根源

你参考的原有代码是WinForm平台的实现,System.Windows.Forms.Cursor类提供了接受非托管光标句柄(IntPtr)的构造函数,但WPF体系下的System.Windows.Input.Cursor没有对应构造,需要通过WPF专属的互操作工具类完成转换。

具体实现

引入依赖命名空间

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

声明非托管方法

// 加载指定dll
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadLibrary(string dllToLoad);
// 释放已加载的dll
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool FreeLibrary(IntPtr hModule);
// 从指定模块加载光标资源
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr LoadCursor(IntPtr hInstance, ushort lpCursorName);

光标生成逻辑

private void LoadCustomCursor()
{
    IntPtr ole32Handle = IntPtr.Zero;
    try
    {
        ole32Handle = LoadLibrary("ole32.dll");
        if (ole32Handle == IntPtr.Zero)
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
        
        // 加载ID为6的拖拽复制光标,可根据需求替换为其他资源ID
        IntPtr cursorHandle = LoadCursor(ole32Handle, 6);
        if (cursorHandle == IntPtr.Zero)
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
        
        // 转换为WPF可用的Cursor实例
        this.Cursor = CursorInteropHelper.Create(cursorHandle);
    }
    finally
    {
        if (ole32Handle != IntPtr.Zero)
        {
            FreeLibrary(ole32Handle);
        }
    }
}

注意事项

  • LoadCursor加载的系统内置光标属于共享资源,无需手动调用DestroyCursor释放句柄,系统会自动管理生命周期
  • 必须在finally块中释放LoadLibrary返回的dll句柄,避免内存泄漏
  • ole32.dll内置常用光标ID参考:ID=2对应拖拽移动光标、ID=3对应不可放置光标、ID=4对应创建快捷方式光标

内容的提问来源于stack exchange,提问作者Nigel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:39:05