有的时候,一个自定义的鼠标光标能给你的程序增色不少。本文这里介绍一下如何在.net桌面程序中自定义鼠标光标。由于.net的桌面程序分为WinForm和WPF两种,这里分别介绍一下。

WinForm程序

对于WinForm程序,可以通过修改Control.Cursor属性来实现光标的修改,如果我们有光标文件的话,可以直接通过如下代码实现自定义光标:

this.Cursor = new Cursor("myCursor.cur");

但这种方式不是本文介绍的重点,本文主要介绍如何自己绘制光标,这样则具有更多的可控性和灵活性。

创建一个自定义光标,首先需要定义需要一个光标结构 ICONINFO ,它的.net版本如下:

public struct IconInfo
    {
        public
bool
fIcon;
        public
int
xHotspot;
        public
int
yHotspot;
        public
IntPtr
hbmMask;
        public
IntPtr
hbmColor;
    }

然后通过GetIconInfo and CreateIconIndirect两个函数来合成光标。完整代码如下:

     public class CursorHelper
{
static class NativeMethods
{
public struct IconInfo
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
} [DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref IconInfo icon); [DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
} public static Cursor CreateCursor(Bitmap bmp, int xHotSpot, int yHotSpot)
{
var icon = new NativeMethods.IconInfo
{
xHotspot = xHotSpot,
yHotspot = yHotSpot,
fIcon = false
}; NativeMethods.GetIconInfo(bmp.GetHicon(), ref icon);
return new Cursor(NativeMethods.CreateIconIndirect(ref icon));
}
}

测试代码为:

using (Bitmap bitmap = new Bitmap(21, 26))
    using (Graphics g = Graphics.FromImage(bitmap))
    {
        g.DrawRectangle(Pens.Red, 0, 0, 20, 25);
        this.Cursor = CursorHelper.CreateCursor(bitmap, 3, 3);
    }

WPF程序

至于WPF程序,和WinForm程序是非常类似的,一方面,它也可以通过光标文件来实现写入Cursor属性来自定义光标文件。

至于自己绘制光标,上面的代码基本上也是可以复用的,不过相对的要重新封装一下,完整代码如下:

     public class CursorHelper
{
static class NativeMethods
{
public struct IconInfo
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
} [DllImport("user32.dll")]
public static extern SafeIconHandle CreateIconIndirect(ref IconInfo icon); [DllImport("user32.dll")]
public static extern bool DestroyIcon(IntPtr hIcon); [DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
} [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeIconHandle()
: base(true)
{
} protected override bool ReleaseHandle()
{
return NativeMethods.DestroyIcon(handle);
}
} static Cursor InternalCreateCursor(System.Drawing.Bitmap bitmap, int xHotSpot, int yHotSpot)
{
var iconInfo = new NativeMethods.IconInfo
{
xHotspot = xHotSpot,
yHotspot = yHotSpot,
fIcon = false
}; NativeMethods.GetIconInfo(bitmap.GetHicon(), ref iconInfo); var cursorHandle = NativeMethods.CreateIconIndirect(ref iconInfo);
return CursorInteropHelper.Create(cursorHandle);
} public static Cursor CreateCursor(UIElement element, int xHotSpot = , int yHotSpot = )
{
element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
element.Arrange(new Rect(new Point(), element.DesiredSize)); var renderTargetBitmap = new RenderTargetBitmap(
(int)element.DesiredSize.Width, (int)element.DesiredSize.Height,
, , PixelFormats.Pbgra32); renderTargetBitmap.Render(element); var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); using (var memoryStream = new MemoryStream())
{
encoder.Save(memoryStream);
using (var bitmap = new System.Drawing.Bitmap(memoryStream))
{
return InternalCreateCursor(bitmap, xHotSpot, yHotSpot);
}
}
}
}

需要注意的是,由于使用的System.Drawing.BitMap,是需要引用System.Drawing.dll的

封装之后,是可以直接传入UIElement作为自绘制的光标的,得益于WPF的强大绘图功能,是可以非常容易的绘制漂亮的光标的。测试代码如下:

this.Cursor= CursorHelper.CreateCursor(new UserControl1());

在.net桌面程序中自定义鼠标光标的更多相关文章

  1. 自定义鼠标光标cursor

    通过css属性 Cursor:url()自定义鼠标光标. {cursor:url('图标路径'),default;} url是自定义鼠标图标路径 default指的是定义默认的光标(通常是一个箭头), ...

  2. WPF 自定义鼠标光标

    在程序中使用自定义鼠标光标的三种方式: RadioButton senderButton = sender as RadioButton; 方式一:                       str ...

  3. Html中自定义鼠标的形状

    Html中自定义鼠标的形状 <html> <head> <title>自定义的鼠标形状</title> <meta http-equiv=&quo ...

  4. 2 weekend110的hadoop的自定义排序实现 + mr程序中自定义分组的实现

    我想得到按流量来排序,而且还是倒序,怎么达到实现呢? 达到下面这种效果, 默认是根据key来排, 我想根据value里的某个排, 解决思路:将value里的某个,放到key里去,然后来排 下面,开始w ...

  5. 微信小程序中自定义modal

    微信小程序中自定义modal .wxml <modal hidden="{{hidden}}" title="这里是title" confirm-text ...

  6. HTML中的鼠标光标属性

    在网页中默认的鼠标指针只有两种,一种是最普通的箭头,另一种是当移动到链接上时出现的“小手”.但现在越来越多的网页都使用了CSS鼠标指针技术,当将鼠标移动到链接上时,可以看到多种不同的效果.CSS可以通 ...

  7. Combox程序中自定义数据源

    有combox控件,命名为cbxPutStatus,在程序中为其手工定义数据源,并绑定 private void POrderSplitFrm_Load(object sender, EventArg ...

  8. JQuery模拟网页中自定义鼠标右键菜单

    题外话.......最近在开发一个网站项目的时候,需要用到网页自定义右键菜单,在网上看了各路前辈大神的操作,头晕目眩,为了达到目的,突然灵机一动,于是便有了这篇文章. 先放个效果图(沾沾自喜,大神勿喷 ...

  9. 自定义鼠标光标,制作cur,设置热点,中心点。

    ..没哈好说的,,只是推荐一个软件 ArtCursor..非常好用. 关于另外一个更改光标的重要问题:鼠标的hotspot,也就是鼠标的作用点问题,本人关于这个问题纠结了很久,始终无法找到更改HCUR ...

随机推荐

  1. POJ-1182 分组并查集

    今天刚发现,之前做的并查集只是贴模板基本就能过,题意改变一点,自己还是不懂,其实我还没入门呢... 题意:食物链,A吃B,B吃C,C吃A,输入m组数据: 1 a b:a 和 b 是同一类 2 a b: ...

  2. Zyxel Switch-How to block a fake DHCP server without enabling DHCP snooping?

    How to block a fake DHCP server without enabling DHCP snooping? Scenario How to block a fake DHCP se ...

  3. 引用计数gc机制使用不当导致内存泄漏

    上一篇文章找同事review了一下,收到的反馈是铺垫太长了,我尽量直入正题,哈哈 最近dbd压测时发现内存泄漏,其实这个问题去年已经暴露了,参见这篇博客[压测周].当时排查不够仔细,在此检讨下.关于d ...

  4. C++中的vector

    opencv中用到了很多vector  整理一下 vector容器是一个模板类,可以存放任何类型的对象(但必须是同一类对象).vector对象可以在运行时高效地添加元素,并且vector中元素是连续存 ...

  5. MongoDB学习笔记一:入门

    文档:多个键及其关联的值『有序』地放置在一起. {"greeting" : "Hello, world!", "foo" : 3}集合:一组 ...

  6. 什么是FTP服务器

    FTP服务器,则是在互联网上提供存储空间的计算机,它们依照FTP协议提供服务. FTP的全称是File Transfer Protocol(文件传输协议).顾名思义,就是专门用来传输文件的协议.简单地 ...

  7. mac android studio 编译时报Class JavaLaunchHelper is implemented in both

    Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Cont ...

  8. Lucene/Solr搜索引擎开发笔记 - 第1章 Solr安装与部署(Jetty篇)

    一.为何开博客写<Lucene/Solr搜索引擎开发笔记> 本人毕业于2011年,2011-2014的三年时间里,在深圳前50强企业工作,从事工业控制领域的机器视觉方向,主要使用语言为C/ ...

  9. Visual Tracker Benchmark

    直接的方法: 首先将代码先拷到benchmark_v1.0/tackers/这个文件夹下,你会发现里面已有好几个算法的代码文件夹了. 这边注意了,我就是这样的,没有注意把代码拷贝进去之后要自己写一个调 ...

  10. python学习-day15:函数作用域、匿名函数、函数式编程、map、filter、reduce函数、内置函数r

    ---恢复内容开始--- 一.全局变量与局部变量 在子程序中定义的变量称为局部变量, 在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序.当全局变量与 ...