在.NET中实现彩色、动态光标(colored cursor)

        在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句柄所占有的资源释放。具体例子见代码:
  
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  System.Runtime.InteropServices;
None.gif
using  System.Windows.Forms;
None.gif
using  System.IO;
None.gif
using  System.Reflection;
None.gif
None.gif
namespace  CursorTest
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 定义一个Form1类型
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class Form1 : Form
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 导入user32.dll中的LoadCursorFromFile函数,用于加载光标文件,并得到光标句柄
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="fileName">光标文件的全名称</param>
ExpandedSubBlockEnd.gif        
/// <returns>光标句柄</returns>

InBlock.gif        [DllImportAttribute("user32.dll")]
InBlock.gif        
public static extern IntPtr LoadCursorFromFile(String fileName);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 导入user32.dll中的DestroyCursor函数,用于销毁光标句柄,清除资源.
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="cursorHandle">需要删除的光标句柄</param>
ExpandedSubBlockEnd.gif        
/// <returns></returns>

InBlock.gif        [DllImportAttribute("user32.dll")]
InBlock.gif        
public static extern uint DestroyCursor(IntPtr cursorHandle);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 从光标库中随机得到一个关闭句柄
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public IntPtr RandomCursorHandle
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                String folder 
= @"K:\ani";
InBlock.gif                String[] files 
= Directory.GetFiles(folder,"*.ani");//获取该目录下的所有的ani文件
InBlock.gif

InBlock.gif                Random random 
= new Random();
InBlock.gif                Int32 index 
= random.Next(0, files.Length);
InBlock.gif
InBlock.gif                IntPtr handle 
= LoadCursorFromFile(files[index]);//根据随机生成的index加载一个光标文件
InBlock.gif
                return handle;//返回光标句柄
ExpandedSubBlockEnd.gif
            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Form1 form 
= new Form1();
InBlock.gif            form.Cursor 
= new Cursor(form.RandomCursorHandle);
InBlock.gif            
//应用程序在空闲时会触发Appliction.Idle事件,这样可以看到光标不挺变化的效果,在不停变化时我们得留言光标句柄的资源释放
InBlock.gif
            Application.Idle += new EventHandler(form.OnApplicationIdle);
InBlock.gif            Application.Run(form);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void OnApplicationIdle(Object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IntPtr handle 
= this.RandomCursorHandle;
InBlock.gif            
//在该Cursor(handle)函数中,MSDN中有这么一句话“处理完光标句柄后必须将其释放”
InBlock.gif            
//因此,我们在构造完Cursor对象后,将handle释放。
InBlock.gif
            this.Cursor = new Cursor(handle);
InBlock.gif            
InBlock.gif            
//若不释放在运行过程中,通过任务管理器,发现改程序进程所占有的GDI对象数一直上升,到大9999后,程序将无法运行。
InBlock.gif
            DestroyCursor(handle);
InBlock.gif
InBlock.gif            
//比较奇怪的是,下面这个语句返回的是true,按照DestroyCursor的意思是销毁该光标句柄所使用的资源,
InBlock.gif            
//但是执行完DestoryCursor后光标还能够正常显示?
InBlock.gif
            System.Console.WriteLine(this.Cursor.Handle == handle);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif      
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

   

转载于:https://www.cnblogs.com/yunwy/archive/2007/08/04/843144.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值