如何在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
相关产品推荐
相关产品推荐

