在win32中实现彩色、动态光标是很easy的事情,只要光标文件是彩色的就可以了。在.NET里面实现起来就不是那么直接了,查阅MSDN发现.NET中的Cursor类不支持彩色或动态光标,原文是这样的 “Cursor 类不支持动画光标(.ani 文件),也不支持彩色(而非黑白色光标)”,这的确有点不爽。遇到这类问题,第一反应就是我们的老办法,先上网查查,看能不能找到解决方案。不负所望,在buidu,google上都能找到相关的文章,问题也得已解决。不过所看到页面的解释也不多,于是在此再次根大家一起讨论学习。
好了,我们言归正传,完成一个彩色或动态光标,大约过程是这样的,使用user32.dll提供的LoadCursorFromFile(String fileName)函数得到一个Windows 句柄,把Windows句柄传给Cursor(IntPtr handle)构造函数,得到一个Cursor对象实例后,调用user32.dll提供的DestroyCursor将Windows句柄所占有的资源释放。具体例子见代码:
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Runtime.InteropServices;
using
System.Windows.Forms;
using
System.IO;
using
System.Reflection;
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace
CursorTest
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 定义一个Form1类型
/// </summary>
public class Form1 : Form
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 导入user32.dll中的LoadCursorFromFile函数,用于加载光标文件,并得到光标句柄
/// </summary>
/// <param name="fileName">光标文件的全名称</param>
/// <returns>光标句柄</returns>
[DllImportAttribute("user32.dll")]
public static extern IntPtr LoadCursorFromFile(String fileName);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 导入user32.dll中的DestroyCursor函数,用于销毁光标句柄,清除资源.
/// </summary>
/// <param name="cursorHandle">需要删除的光标句柄</param>
/// <returns></returns>
[DllImportAttribute("user32.dll")]
public static extern uint DestroyCursor(IntPtr cursorHandle);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 从光标库中随机得到一个关闭句柄
/// </summary>
public IntPtr RandomCursorHandle
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
String folder = @"K:\ani";
String[] files = Directory.GetFiles(folder,"*.ani");//获取该目录下的所有的ani文件
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Random random = new Random();
Int32 index = random.Next(0, files.Length);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IntPtr handle = LoadCursorFromFile(files[index]);//根据随机生成的index加载一个光标文件
return handle;//返回光标句柄
}
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Main()
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Form1 form = new Form1();
form.Cursor = new Cursor(form.RandomCursorHandle);
//应用程序在空闲时会触发Appliction.Idle事件,这样可以看到光标不挺变化的效果,在不停变化时我们得留言光标句柄的资源释放
Application.Idle += new EventHandler(form.OnApplicationIdle);
Application.Run(form);
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void OnApplicationIdle(Object sender, EventArgs e)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
IntPtr handle = this.RandomCursorHandle;
//在该Cursor(handle)函数中,MSDN中有这么一句话“处理完光标句柄后必须将其释放”
//因此,我们在构造完Cursor对象后,将handle释放。
this.Cursor = new Cursor(handle);
//若不释放在运行过程中,通过任务管理器,发现改程序进程所占有的GDI对象数一直上升,到大9999后,程序将无法运行。
DestroyCursor(handle);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//比较奇怪的是,下面这个语句返回的是true,按照DestroyCursor的意思是销毁该光标句柄所使用的资源,
//但是执行完DestoryCursor后光标还能够正常显示?
System.Console.WriteLine(this.Cursor.Handle == handle);
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
}
转载于:https://www.cnblogs.com/yunwy/archive/2007/08/04/843144.html