我正在开发一款SDG(单显示组件)应用程序,为此我需要在单个窗口中使用多个光标(至少需要不同颜色的光标)。我了解到,使用C#只能使用黑色和白色光标,这并不能解决我的问题。
我正在开发一款SDG(单显示组件)应用程序,为此我需要在单个窗口中使用多个光标(至少需要不同颜色的光标)。我了解到,使用C#只能使用黑色和白色光标,这并不能解决我的问题。
Cursor类设计得相当糟糕。由于某种神秘的原因,它使用了一个遗留的COM接口(IPicture),该接口不支持彩色和动画光标。但是可以通过一些相当丑陋的操作来解决这个问题:
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
static class NativeMethods {
public static Cursor LoadCustomCursor(string path) {
IntPtr hCurs = LoadCursorFromFile(path);
if (hCurs == IntPtr.Zero) throw new Win32Exception();
var curs = new Cursor(hCurs);
// Note: force the cursor to own the handle so it gets released properly
var fi = typeof(Cursor).GetField("ownHandle", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(curs, true);
return curs;
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadCursorFromFile(string path);
}
使用示例:
this.Cursor = NativeMethods.LoadCustomCursor(@"c:\windows\cursors\aero_busy.ani");
Control
构造函数内部加载具有路径目录的文件,就像"aero_busy.ani"
(假设.ani
文件存在于根应用程序目录中),那么这将使Designer
停止工作。因此,在我的情况下,我返回了nullptr
而不是抛出Win32Exception
,然后仅在Cursor
与nullptr
不同的情况下更改它。 - Simple这个帖子相当老了,但是它在谷歌上排名靠前,所以这里提供VS 2019的答案:
someControl.Cursor = new Cursor(Properties.Resources.somePNG.GetHicon());
你应该将带有透明度的'somePNG.png'添加为项目资源。
希望这能帮助到2020年的某些人。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace MID
{
public partial class CustomCursor : Form
{
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr LoadCursorFromFile(string filename);
public CustomCursor()
{
InitializeComponent();
Bitmap bmp = (Bitmap)Bitmap.FromFile("Path of the cursor file saved as .bmp");
bmp.MakeTransparent(Color.Black);
IntPtr ptr1 = blue.GetHicon();
Cursor cur = new Cursor(ptr1);
this.Cursor = cur;
}
}
}
var myCursor = new Cursor("myCursor.cur");
在加载后,您可以像这样设置任何控件的光标:
myControl.Cursor = myCursor;
光标还可以接受流作为构造函数参数。这意味着您可以从嵌入在应用程序中的资源加载,而不是从文件系统中加载。
Windows 不允许您拥有多个光标,但您可以在控件上绘制多个光标。您可以使用光标对象的 Draw
方法,如下所示:
myCursor.Draw(g, new Rectangle(...));
如果您正在使用TCP/IP在客户端之间发送光标数据,则这应该足以工作。
然而,有一些应用程序支持在单个PC上进行多个输入。 (例如,Rag Doll Kung Fu)对于此,您需要查看.NET框架不支持的内容。
您可能需要研究一些USB调用的PInvoke。(我在这方面没有太多经验,所以无法详细说明。)