我正在尝试在Cursor上使用自定义图像,我使用这些代码完成了它。
public static class cursorHelper
{
public static Cursor vertical = new Cursor(Application.GetResourceStream(getFromResource("PenCADwpf", "Images/cursors/Vertical.ico")).Stream);
public static Cursor horizontal = new Cursor(Application.GetResourceStream(getFromResource("PenCADwpf", "Images/cursors/Horizontal.ico")).Stream);
public static Uri getFromResource(string psAssemblyName, string psResourceName)
{
Uri oUri = new Uri("pack://application:,,,/" + psAssemblyName + ";component/" + psResourceName, UriKind.RelativeOrAbsolute);
return oUri;
}
public static ImageSource getImageSourceFromResource(string psAssemblyName, string psResourceName)
{
Uri oUri = getFromResource(psAssemblyName, psResourceName);
return BitmapFrame.Create(oUri);
}
}
在代码中使用
private void btnVerticalMullion_Click(object sender, RoutedEventArgs e)
{
this.Cursor = cursorHelper.vertical;
}
我的问题是光标的热点是左下角。我需要将其更改为图像的0,0(左上角)点。有人可以帮帮我吗? 提前谢谢,
答案 0 :(得分:3)
这是因为您使用.ICO文件而不是.CUR文件作为Cursor
类的数据。
虽然.ICO和.CUR文件格式相似,但.ICO格式不包含热点信息。
您有两个选择:
将您的.ICO文件转换为.CUR文件,并将其作为资源嵌入 通过使用可在Web上找到的转换实用程序来执行此操作,或者在Visual Studio中创建新的.CUR文件,然后从.ICO文件中复制并粘贴数据。
将它们保存为.ICO文件但是破解数据,以便在传递给Cursor类时遵循CUR格式。
以下是修改ICO流以将其转换为CUR格式的示例代码。
在这个例子中,我用一个包含单个32X32X4bit BMP图像的ICO文件对其进行了测试,我希望光标有一个(15,15)热点。
这段代码只是为了让你开始,如果沿着这条路走......它需要更多的代码来处理错误,以及处理包含多个图标图像的ICO文件的能力(即如果有多个条目)等。
您还可以使用BinaryWriter
更自然地处理数据,例如通过使用Write(UInt16)
来写出使用2个字节(即超过255个)的热点坐标。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Windows.Resources;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Uri uri = new Uri("pack://application:,,,/test.ico");
Stream iconstream = GetCURFromICO(uri, 15, 15 );
Cursor cursor = new Cursor(iconstream);
this.Cursor = cursor;
}
public static Stream GetCursorFromICO(Uri uri, byte hotspotx, byte hotspoty)
{
StreamResourceInfo sri = Application.GetResourceStream(uri);
Stream s = sri.Stream;
byte []buffer = new byte[s.Length];
s.Read(buffer, 0, (int)s.Length);
MemoryStream ms = new MemoryStream();
buffer[2] = 2; // change to CUR file type
buffer[10] = hotspotx;
buffer[12] = hotspoty;
ms.Write(buffer, 0, (int)s.Length);
ms.Position = 0;
return ms;
}
public static Stream GetCURFromICOAlternativeMethod(Uri uri, byte hotspotx, byte hotspoty)
{
StreamResourceInfo sri = Application.GetResourceStream(uri);
Stream s = sri.Stream;
byte []buffer = new byte[s.Length];
MemoryStream ms = new MemoryStream();
ms.WriteByte(0); // always 0
ms.WriteByte(0);
ms.WriteByte(2); // change file type to CUR
ms.WriteByte(0);
ms.WriteByte(1); // 1 icon in table
ms.WriteByte(0);
s.Position = 6; // skip over first 6 bytes in ICO as we just wrote
s.Read(buffer, 0, 4);
ms.Write(buffer, 0, 4);
ms.WriteByte(hotspotx);
ms.WriteByte(0);
ms.WriteByte(hotspoty);
ms.WriteByte(0);
s.Position += 4; // skip 4 bytes as we just wrote our own
int remaining = (int)s.Length - 14;
s.Read(buffer, 0, remaining);
ms.Write(buffer, 0, remaining);
ms.Position = 0;
return ms;
}
}
}
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
</Window>