如何自定义光标文件并将其添加到项目中?
How to Customize and add Cursor Files to a project?
快速提问:
我在使用 Wpf 应用程序,我使用此例程在鼠标悬停在图像上时更改光标形状:
private void mainGrid_MouseEnter(object sender, MouseEventArgs e)
{
mainImage.Cursor = Cursors.Hand;
}
private void mainGrid_MouseLeave(object sender, MouseEventArgs e)
{
mainImage.Cursor = Cursors.Arrow;
}
输出:
我怎样才能得到下面的形状?
我希望这可以简单地工作:
foreach (var finger in fingers.Skip(2)) { finger.Extend(); }
但是不行..编程不是那样的..
我想要的形状在游标中不可用:Cursors Class
正如其他人所提到的,您需要为此形状自定义光标。
我对这段代码并不特别自豪,但我设法让自己陷入困境,需要在项目中没有任何新资源的情况下这样做,所以这里有一个独立的自定义此特定游标的游标创建者。
您可以将它创建的 HandCursor 分配给您的表单,就像任何其他光标一样,例如:
public Example()
{
PictureBox box = new PictureBox();
box.Bounds = new Rectangle(10, 10, 100, 100);
box.Cursor = HandCursor;
box.MouseDown += Box_MouseDown;
box.MouseUp += Box_MouseUp;
box.BorderStyle = BorderStyle.Fixed3D;
Controls.Add(box);
}
void Box_MouseUp(object sender, MouseEventArgs e)
{
((Control)sender).Cursor = HandCursor;
}
void Box_MouseDown(object sender, MouseEventArgs e)
{
((Control)sender).Cursor = HandGrabCursor;
}
这里是代码的核心:
Cursor m_HandCursor = null;
Cursor HandCursor
{
get
{
if (m_HandCursor == null)
{
m_HandCursor = CursorFromString(
"AAACAAEAICAAABAAFACoEAAAFgAAACgAAAAgAAAAQ{A5}EAI{A62}aBgM3GgYD/xoGA/8a" +
"BgP/GgYD/xoGA/8aBgP/GgYD/xoGA/8aBgO6{A70}GgYDNxoGA73Ny8r/39/f/93d3f/a2" +
"tr/2NjY/9bW1v/V1dX/09PT/xoGA94{A6a}BoGAzcaBgO909HR/+Xl5f/j4+P/4eHh/97e" +
"3v/c3Nz/2tra/9jY2P/W1tb/GgYD3hoGAz{A61}aBgM3GgYDvdnX1//s7Oz/6urq/+fn5/" +
"/l5eX/4+Pj/+Dg4P/e3t7/3Nzc/9ra2v8aBgOHGgYDhw{A5f}BoGA73f3dz/8/Pz//Hx8f" +
"/u7u7/7Ozs/+np6f/n5+f/5OTk/+Li4v/g4OD/3d3d/7Kurf8aBgPV{A5b}aBgNjGgYDtP" +
"n5+f/IxMP/9fX1//Ly8v/w8PD/7u7u/+vr6//p6en/5ubm/+Tk5P/i4uL/39/f/xoGA94a" +
"BgMw{A50}GgYDNhoGA7rm5OT//Pz8/4N5d//4+Pj/9vb2//T09P/y8vL/8PDw/+3t7f/r6" +
"+v/6Ojo/+bm5v/j4+P/GgYDhxoGA4c{A50}aBgO66Obl{/7}+/v7/GgYD//v7+//6+vr/+" +
"Pj4//b29v/09PT/8vLy/+/v7//t7e3/6urq/+jo6P+6trX/GgYD1Q{A4f}BoGA//o5uX/6" +
"Obl/xoGA7oaBgP//v7+//39/f/7+/v/+fn5//j4+P/19fX/8/Pz//Hx8f/v7+//7Ozs/+r" +
"q6v8aBgP/{A50}GgYDuhoGA/8aBgO6GgYDNhoGA{/d}7+/v/8/Pz/+/v7//n5+f/39/f/9" +
"fX1//Pz8//x8fH/7u7u/xoGA/8{A65}GgYD{/17}9/f3//Pz8//r6+v/5+fn/GgYD//X19" +
"f/y8vL/GgYD/w{A65}aBgP{/c}Pysr{/b}8aBgP//f39//z8/P8aBgP/+Pj4//b29v8aBg" +
"P/{A60}GgYDMDgmJP{/b}4Z7ev{/b}xoGA{/8}v7+/xoGA//7+/v/+vr6/xoGA/8{A60}a" +
"BgOHhnt6{/c}QC8t{/c}GgYD{/c}GgYD//7+/v/9/f3/GgYD/w{A5f}BoGA9XPysr{/6}8" +
"/Kyv8aBgP{/b}8aBgP{/b}8aBgP{/6}8/Kyv8aBgO6{A60}GgYD{/c}GgYDhxoGA{/c}xo" +
"GA{/c}xoGA//Pysr/GgYDuhoGAxo{A60}aBgP{/b}8aBgOHGgYD{/c}GgYD{/7}Pysr/Gg" +
"YD/xoGA7oaBgMa{A65}BoGA7r{/a}xoGA4caBgP{/b}8aBgP/GgYD/xoGA7oaBgM2{A70}" +
"GgYDNhoGA7oaBgO6GgYDNhoGA7r{/a}xoGA7o{A95}GgYDNhoGA7oaBgO6GgYDNg{A84a}" +
"//AD///gA///wAH//4AB//+AAf//AAD//gAA//4AAP/+AAD//gAA///gAP//4AD//8AA//" +
"/AAP//wAD//8AA///AAf//wAf//8A////8P{/41}8=");
}
return m_HandCursor;
}
}
Cursor m_HandGrabCursor = null;
Cursor HandGrabCursor
{
get
{
if (m_HandGrabCursor == null)
{
m_HandGrabCursor = CursorFromString(
"AAACAAEAICAAABAAFACoEAAAFgAAACgAAAAgAAAAQ{A5}EAI{A62}aBgM3GgYD/xoGA/8a" +
"BgP/GgYD/xoGA/8aBgP/GgYD/xoGA/8aBgO6{A70}GgYDNxoGA73Pzc3/4eHh/97e3v/b2" +
"9v/2dnZ/9bW1v/U1NT/0tLS/xoGA94{A6a}BoGAzcaBgO919XV/+rq6v/n5+f/4+Pj/+Dg" +
"4P/d3d3/29vb/9jY2P/W1tb/GgYD3hoGAz{A61}aBgM3GgYDvd/d3P/y8vL/7+/v/+zs7P" +
"/p6en/5ubm/+Pj4//g4OD/3d3d/9ra2v8aBgOHGgYDhw{A5f}BoGA73l4+P/+vr6//f39/" +
"/19fX/8vLy/+/v7//r6+v/6Ojo/+Xl5f/i4uL/39/f/7Ovrv8aBgPV{A5b}aBgNjGgYDtP" +
"{/5}Nycj/+/v7//n5+f/39/f/9PT0//Hx8f/u7u7/6+vr/+fn5//k5OT/4eHh/xoGA94aB" +
"gMw{A50}GgYDNhoGA7ro5uX{/6}4Z7ev/+/v7//f39//v7+//5+fn/9vb2//Pz8//w8PD/" +
"7e3t/+rq6v/n5+f/GgYDhxoGA4c{A50}aBgO66Obl{/c}GgYD{/d}v7+//z8/P/6+vr/+P" +
"j4//X19f/y8vL/7+/v/+zs7P+9ubj/GgYD1Q{A4f}BoGA//o5uX/6Obl/xoGA7oaBgP{/1" +
"7}7+/v/8/Pz/+vr6//f39//19fX/8vLy/+/v7/8aBgP/{A50}GgYDuhoGA/8aBgO6GgYDN" +
"hoGA{/22}9/f3/+/v7//n5+f/39/f/9PT0/xoGA/8{A65}GgYD{/27}+/v7/GgYD//v7+/" +
"/5+fn/GgYD/w{A65}aBgP{/b}8aBgP{/b}8aBgP{/b}8aBgP//v7+/8zIx/8aBgO6{A65}" +
"BoGA{/c}xoGA{/c}xoGA{/c}xoGA//Pysr/GgYDuhoGAxo{A65}GgYD/8/Kyv{/6}GgYD{" +
"/c}GgYD{/7}Pysr/GgYD/xoGA7oaBgMa{A6b}aBgM2GgYDuhoGA/8aBgO6{/a}8aBgO6Gg" +
"YD/xoGA7oaBgM2{A85}BoGAzYaBgO6GgYDuhoGAzY{Aaf5}//AD///gA///wAH//4AB//+" +
"AAf//AAD//gAA//4AAP/+AAD//gAA///gAP//4AD//+AA///gAf//4Af///w{/57}8=");
}
return m_HandGrabCursor;
}
}
Cursor CursorFromString(string data)
{
byte[] bits = Convert.FromBase64String(
Regex.Replace(data,
"\{(.)([0-9a-f]+)\}",
delegate(Match m)
{
return new string(
m.Groups[1].Value[0],
int.Parse(m.Groups[2].Value,
System.Globalization.NumberStyles.HexNumber));
}
)
);
bits[2] = 1;
using (MemoryStream stream = new MemoryStream(bits))
{
return new Cursor(stream);
#if false
// Version for Windows Forms
using (Icon icon = new Icon(stream))
{
WinAPI.ICONINFO info = new WinAPI.ICONINFO();
WinAPI.GetIconInfo(icon.Handle, out info);
info.fIcon = false;
info.xHotspot = bits[10];
info.yHotspot = bits[12];
IntPtr hCursor = WinAPI.CreateIconIndirect(ref info);
Cursor ret = new Cursor(hCursor);
return ret;
}
#endif
}
}
static class WinAPI
{
[DllImport("user32.dll")]
public static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
[DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref ICONINFO piconinfo);
[StructLayout(LayoutKind.Sequential)]
public struct ICONINFO
{
public bool fIcon;
public Int32 xHotspot;
public Int32 yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
}
为了获得这样的光标,您需要获得(或创建)自定义光标。 Windows 中没有这样的游标。可以使用 Visual Studio 的内置 Image Editor for Icons.
创建您自己的光标
创建您自己的游标
首先打开 Add New Item
对话框。
然后向下滚动并 select Cursor File
,给它一个你选择的名字。
它现在将在所谓的 图标图像编辑器 中打开您的新光标文件。现在您可以使用铅笔或任何其他不同的绘图工具开始绘图(也可以粘贴图像,但正如您所见,光标最初具有 1 位颜色格式 - 这意味着只有两种颜色:黑色和白色。这可以通过添加新的图像类型进行更改)。
现在我们必须为游标指定一个hot spot。热点是图标中的位置,Windows 用来跟踪指针的实际位置(为简单起见,您可以将其称为光标的点击点)。正常的 Windows 7 Aero Arrow 在 (0, 0) - 左上角有热点。
要指定光标的热点,我们必须使用 Set Hot Spot Tool
。然后单击要用作光标图标中的热点的特定像素。对于这个游标,我选择了 (9, 8).
设置热点在(9, 8):
保存所有内容,然后转到 Solution Explorer
,右键单击您的项目并按 Properties
。然后转到 Resources
选项卡并单击 Add Resource
和 Add Existing File...
。
现在找到您的项目文件夹 select 并打开光标文件。
最后的非代码步骤是 select 您的光标在 Solution Explorer
中,转到 Properties
窗格并将 Build Action
设置为None
。这是为了防止它被添加到编译的可执行文件中两次,因为它已经作为资源添加了。
重要提示: 不要 对位于 Resources
文件夹中的光标文件执行此操作!
在您的应用程序中使用自定义光标
现在上代码,其实很简单。由于您的光标现在已作为字节数组资源添加,您只需将其加载到 MemoryStream
中,然后将该内存流传递到 Cursor
class 的构造函数中。为了简单和可读性,我把这段代码放在另一个 class.
public static class CursorHelper
{
public static Cursor FromByteArray(byte[] array)
{
using (MemoryStream memoryStream = new MemoryStream(array))
{
return new Cursor(memoryStream);
}
}
}
现在您可以继续在 form/control/etc 中声明光标在 class 级。然后您就可以使用它了!
private Cursor OpenHand = CursorHelper.FromByteArray(Properties.Resources.CursorOpenHand);
public MainWindow()
{
InitializeComponent();
this.Cursor = OpenHand;
}
用法示例
我根据您的规格做了一个例子;当您按住鼠标时,一只正常张开的手会变成一只抓握的手:
private Cursor OpenHand = CursorHelper.FromByteArray(Properties.Resources.CursorOpenHand);
private Cursor GrabbingHand = CursorHelper.FromByteArray(Properties.Resources.CursorGrabbingHand);
public MainWindow()
{
InitializeComponent();
this.Cursor = OpenHand;
this.MouseDown += this.MainWindow_MouseDown;
this.MouseUp += this.MainWindow_MouseUp;
}
private void MainWindow_MouseDown(object sender, MouseEventArgs e)
{
((Control)sender).Cursor = GrabbingHand;
}
private void MainWindow_MouseUp(object sender, MouseEventArgs e)
{
((Control)sender).Cursor = OpenHand;
}
盈利!
以下是我使用的游标:
您可以将游标编码为 base-64 字符串,然后使用 Convert.FromBase64String
:
将该 base-64 字符串转回游标
byte[] HandGrabCursor = Convert.FromBase64String("AAACAAEAICAAAAkACAAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAgAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAfwAAAP+AAAH/gAAB/8AAAH/AAAB/wAAA/0AAANsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////////////////////////////////////////////////gH///4B///8Af//+AD///AA///wAH//+AB///wAf//4AH//+AD///yT/////////////////////////////8=");
using MemoryStream stream = new MemoryStream(HandGrabCursor);
Cursor = new Cursor(stream);
快速提问:
我在使用 Wpf 应用程序,我使用此例程在鼠标悬停在图像上时更改光标形状:
private void mainGrid_MouseEnter(object sender, MouseEventArgs e)
{
mainImage.Cursor = Cursors.Hand;
}
private void mainGrid_MouseLeave(object sender, MouseEventArgs e)
{
mainImage.Cursor = Cursors.Arrow;
}
输出:
我怎样才能得到下面的形状?
我希望这可以简单地工作:
foreach (var finger in fingers.Skip(2)) { finger.Extend(); }
但是不行..编程不是那样的..
我想要的形状在游标中不可用:Cursors Class
正如其他人所提到的,您需要为此形状自定义光标。
我对这段代码并不特别自豪,但我设法让自己陷入困境,需要在项目中没有任何新资源的情况下这样做,所以这里有一个独立的自定义此特定游标的游标创建者。
您可以将它创建的 HandCursor 分配给您的表单,就像任何其他光标一样,例如:
public Example()
{
PictureBox box = new PictureBox();
box.Bounds = new Rectangle(10, 10, 100, 100);
box.Cursor = HandCursor;
box.MouseDown += Box_MouseDown;
box.MouseUp += Box_MouseUp;
box.BorderStyle = BorderStyle.Fixed3D;
Controls.Add(box);
}
void Box_MouseUp(object sender, MouseEventArgs e)
{
((Control)sender).Cursor = HandCursor;
}
void Box_MouseDown(object sender, MouseEventArgs e)
{
((Control)sender).Cursor = HandGrabCursor;
}
这里是代码的核心:
Cursor m_HandCursor = null;
Cursor HandCursor
{
get
{
if (m_HandCursor == null)
{
m_HandCursor = CursorFromString(
"AAACAAEAICAAABAAFACoEAAAFgAAACgAAAAgAAAAQ{A5}EAI{A62}aBgM3GgYD/xoGA/8a" +
"BgP/GgYD/xoGA/8aBgP/GgYD/xoGA/8aBgO6{A70}GgYDNxoGA73Ny8r/39/f/93d3f/a2" +
"tr/2NjY/9bW1v/V1dX/09PT/xoGA94{A6a}BoGAzcaBgO909HR/+Xl5f/j4+P/4eHh/97e" +
"3v/c3Nz/2tra/9jY2P/W1tb/GgYD3hoGAz{A61}aBgM3GgYDvdnX1//s7Oz/6urq/+fn5/" +
"/l5eX/4+Pj/+Dg4P/e3t7/3Nzc/9ra2v8aBgOHGgYDhw{A5f}BoGA73f3dz/8/Pz//Hx8f" +
"/u7u7/7Ozs/+np6f/n5+f/5OTk/+Li4v/g4OD/3d3d/7Kurf8aBgPV{A5b}aBgNjGgYDtP" +
"n5+f/IxMP/9fX1//Ly8v/w8PD/7u7u/+vr6//p6en/5ubm/+Tk5P/i4uL/39/f/xoGA94a" +
"BgMw{A50}GgYDNhoGA7rm5OT//Pz8/4N5d//4+Pj/9vb2//T09P/y8vL/8PDw/+3t7f/r6" +
"+v/6Ojo/+bm5v/j4+P/GgYDhxoGA4c{A50}aBgO66Obl{/7}+/v7/GgYD//v7+//6+vr/+" +
"Pj4//b29v/09PT/8vLy/+/v7//t7e3/6urq/+jo6P+6trX/GgYD1Q{A4f}BoGA//o5uX/6" +
"Obl/xoGA7oaBgP//v7+//39/f/7+/v/+fn5//j4+P/19fX/8/Pz//Hx8f/v7+//7Ozs/+r" +
"q6v8aBgP/{A50}GgYDuhoGA/8aBgO6GgYDNhoGA{/d}7+/v/8/Pz/+/v7//n5+f/39/f/9" +
"fX1//Pz8//x8fH/7u7u/xoGA/8{A65}GgYD{/17}9/f3//Pz8//r6+v/5+fn/GgYD//X19" +
"f/y8vL/GgYD/w{A65}aBgP{/c}Pysr{/b}8aBgP//f39//z8/P8aBgP/+Pj4//b29v8aBg" +
"P/{A60}GgYDMDgmJP{/b}4Z7ev{/b}xoGA{/8}v7+/xoGA//7+/v/+vr6/xoGA/8{A60}a" +
"BgOHhnt6{/c}QC8t{/c}GgYD{/c}GgYD//7+/v/9/f3/GgYD/w{A5f}BoGA9XPysr{/6}8" +
"/Kyv8aBgP{/b}8aBgP{/b}8aBgP{/6}8/Kyv8aBgO6{A60}GgYD{/c}GgYDhxoGA{/c}xo" +
"GA{/c}xoGA//Pysr/GgYDuhoGAxo{A60}aBgP{/b}8aBgOHGgYD{/c}GgYD{/7}Pysr/Gg" +
"YD/xoGA7oaBgMa{A65}BoGA7r{/a}xoGA4caBgP{/b}8aBgP/GgYD/xoGA7oaBgM2{A70}" +
"GgYDNhoGA7oaBgO6GgYDNhoGA7r{/a}xoGA7o{A95}GgYDNhoGA7oaBgO6GgYDNg{A84a}" +
"//AD///gA///wAH//4AB//+AAf//AAD//gAA//4AAP/+AAD//gAA///gAP//4AD//8AA//" +
"/AAP//wAD//8AA///AAf//wAf//8A////8P{/41}8=");
}
return m_HandCursor;
}
}
Cursor m_HandGrabCursor = null;
Cursor HandGrabCursor
{
get
{
if (m_HandGrabCursor == null)
{
m_HandGrabCursor = CursorFromString(
"AAACAAEAICAAABAAFACoEAAAFgAAACgAAAAgAAAAQ{A5}EAI{A62}aBgM3GgYD/xoGA/8a" +
"BgP/GgYD/xoGA/8aBgP/GgYD/xoGA/8aBgO6{A70}GgYDNxoGA73Pzc3/4eHh/97e3v/b2" +
"9v/2dnZ/9bW1v/U1NT/0tLS/xoGA94{A6a}BoGAzcaBgO919XV/+rq6v/n5+f/4+Pj/+Dg" +
"4P/d3d3/29vb/9jY2P/W1tb/GgYD3hoGAz{A61}aBgM3GgYDvd/d3P/y8vL/7+/v/+zs7P" +
"/p6en/5ubm/+Pj4//g4OD/3d3d/9ra2v8aBgOHGgYDhw{A5f}BoGA73l4+P/+vr6//f39/" +
"/19fX/8vLy/+/v7//r6+v/6Ojo/+Xl5f/i4uL/39/f/7Ovrv8aBgPV{A5b}aBgNjGgYDtP" +
"{/5}Nycj/+/v7//n5+f/39/f/9PT0//Hx8f/u7u7/6+vr/+fn5//k5OT/4eHh/xoGA94aB" +
"gMw{A50}GgYDNhoGA7ro5uX{/6}4Z7ev/+/v7//f39//v7+//5+fn/9vb2//Pz8//w8PD/" +
"7e3t/+rq6v/n5+f/GgYDhxoGA4c{A50}aBgO66Obl{/c}GgYD{/d}v7+//z8/P/6+vr/+P" +
"j4//X19f/y8vL/7+/v/+zs7P+9ubj/GgYD1Q{A4f}BoGA//o5uX/6Obl/xoGA7oaBgP{/1" +
"7}7+/v/8/Pz/+vr6//f39//19fX/8vLy/+/v7/8aBgP/{A50}GgYDuhoGA/8aBgO6GgYDN" +
"hoGA{/22}9/f3/+/v7//n5+f/39/f/9PT0/xoGA/8{A65}GgYD{/27}+/v7/GgYD//v7+/" +
"/5+fn/GgYD/w{A65}aBgP{/b}8aBgP{/b}8aBgP{/b}8aBgP//v7+/8zIx/8aBgO6{A65}" +
"BoGA{/c}xoGA{/c}xoGA{/c}xoGA//Pysr/GgYDuhoGAxo{A65}GgYD/8/Kyv{/6}GgYD{" +
"/c}GgYD{/7}Pysr/GgYD/xoGA7oaBgMa{A6b}aBgM2GgYDuhoGA/8aBgO6{/a}8aBgO6Gg" +
"YD/xoGA7oaBgM2{A85}BoGAzYaBgO6GgYDuhoGAzY{Aaf5}//AD///gA///wAH//4AB//+" +
"AAf//AAD//gAA//4AAP/+AAD//gAA///gAP//4AD//+AA///gAf//4Af///w{/57}8=");
}
return m_HandGrabCursor;
}
}
Cursor CursorFromString(string data)
{
byte[] bits = Convert.FromBase64String(
Regex.Replace(data,
"\{(.)([0-9a-f]+)\}",
delegate(Match m)
{
return new string(
m.Groups[1].Value[0],
int.Parse(m.Groups[2].Value,
System.Globalization.NumberStyles.HexNumber));
}
)
);
bits[2] = 1;
using (MemoryStream stream = new MemoryStream(bits))
{
return new Cursor(stream);
#if false
// Version for Windows Forms
using (Icon icon = new Icon(stream))
{
WinAPI.ICONINFO info = new WinAPI.ICONINFO();
WinAPI.GetIconInfo(icon.Handle, out info);
info.fIcon = false;
info.xHotspot = bits[10];
info.yHotspot = bits[12];
IntPtr hCursor = WinAPI.CreateIconIndirect(ref info);
Cursor ret = new Cursor(hCursor);
return ret;
}
#endif
}
}
static class WinAPI
{
[DllImport("user32.dll")]
public static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
[DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref ICONINFO piconinfo);
[StructLayout(LayoutKind.Sequential)]
public struct ICONINFO
{
public bool fIcon;
public Int32 xHotspot;
public Int32 yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
}
为了获得这样的光标,您需要获得(或创建)自定义光标。 Windows 中没有这样的游标。可以使用 Visual Studio 的内置 Image Editor for Icons.
创建您自己的光标创建您自己的游标
首先打开
Add New Item
对话框。
然后向下滚动并 select
Cursor File
,给它一个你选择的名字。
它现在将在所谓的 图标图像编辑器 中打开您的新光标文件。现在您可以使用铅笔或任何其他不同的绘图工具开始绘图(也可以粘贴图像,但正如您所见,光标最初具有 1 位颜色格式 - 这意味着只有两种颜色:黑色和白色。这可以通过添加新的图像类型进行更改)。
现在我们必须为游标指定一个hot spot。热点是图标中的位置,Windows 用来跟踪指针的实际位置(为简单起见,您可以将其称为光标的点击点)。正常的 Windows 7 Aero Arrow 在 (0, 0) - 左上角有热点。
要指定光标的热点,我们必须使用
Set Hot Spot Tool
。然后单击要用作光标图标中的热点的特定像素。对于这个游标,我选择了 (9, 8).设置热点在(9, 8):
保存所有内容,然后转到
Solution Explorer
,右键单击您的项目并按Properties
。然后转到Resources
选项卡并单击Add Resource
和Add Existing File...
。现在找到您的项目文件夹 select 并打开光标文件。
最后的非代码步骤是 select 您的光标在
Solution Explorer
中,转到Properties
窗格并将Build Action
设置为None
。这是为了防止它被添加到编译的可执行文件中两次,因为它已经作为资源添加了。重要提示: 不要 对位于
Resources
文件夹中的光标文件执行此操作!
在您的应用程序中使用自定义光标
现在上代码,其实很简单。由于您的光标现在已作为字节数组资源添加,您只需将其加载到 MemoryStream
中,然后将该内存流传递到 Cursor
class 的构造函数中。为了简单和可读性,我把这段代码放在另一个 class.
public static class CursorHelper
{
public static Cursor FromByteArray(byte[] array)
{
using (MemoryStream memoryStream = new MemoryStream(array))
{
return new Cursor(memoryStream);
}
}
}
现在您可以继续在 form/control/etc 中声明光标在 class 级。然后您就可以使用它了!
private Cursor OpenHand = CursorHelper.FromByteArray(Properties.Resources.CursorOpenHand);
public MainWindow()
{
InitializeComponent();
this.Cursor = OpenHand;
}
用法示例
我根据您的规格做了一个例子;当您按住鼠标时,一只正常张开的手会变成一只抓握的手:
private Cursor OpenHand = CursorHelper.FromByteArray(Properties.Resources.CursorOpenHand);
private Cursor GrabbingHand = CursorHelper.FromByteArray(Properties.Resources.CursorGrabbingHand);
public MainWindow()
{
InitializeComponent();
this.Cursor = OpenHand;
this.MouseDown += this.MainWindow_MouseDown;
this.MouseUp += this.MainWindow_MouseUp;
}
private void MainWindow_MouseDown(object sender, MouseEventArgs e)
{
((Control)sender).Cursor = GrabbingHand;
}
private void MainWindow_MouseUp(object sender, MouseEventArgs e)
{
((Control)sender).Cursor = OpenHand;
}
盈利!
以下是我使用的游标:
您可以将游标编码为 base-64 字符串,然后使用 Convert.FromBase64String
:
byte[] HandGrabCursor = Convert.FromBase64String("AAACAAEAICAAAAkACAAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAgAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAfwAAAP+AAAH/gAAB/8AAAH/AAAB/wAAA/0AAANsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////////////////////////////////////////////////gH///4B///8Af//+AD///AA///wAH//+AB///wAf//4AH//+AD///yT/////////////////////////////8=");
using MemoryStream stream = new MemoryStream(HandGrabCursor);
Cursor = new Cursor(stream);