【问题标题】:Set Custom Cursor Image Hotspot in WPF在 WPF 中设置自定义光标图像热点
【发布时间】:2013-11-16 02:59:36
【问题描述】:

我正在尝试在 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(左上角)点。任何机构可以帮助我吗? 提前致谢,

【问题讨论】:

    标签: c# wpf image cursor


    【解决方案1】:

    这是因为您使用 .ICO 文件而不是 .CUR 文件作为 Cursor 类的数据。

    虽然 .ICO 和 .CUR 文件格式相似,但 .ICO 格式不包含热点信息。

    你有两个选择:

    • 将您的 .ICO 文件转换为 .CUR 文件并将其嵌入为资源

      使用您可以在网络上找到的转换实用程序来执行此操作,
      或
      在 Visual Studio 中创建一个新的 .CUR 文件,然后从您的 .ICO 文件中复制并粘贴数据。

      李>
    • 将它们保存为 .ICO 文件,但修改数据,使其在传递给 Cursor 类时遵循 CUR 格式。

    下面是一些修改 ICO 流以将其转换为 CUR 格式的示例代码。

    在此示例中,我使用包含单个 32X32X4 位 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>
    

    【讨论】:

      猜你喜欢
      • 2013-11-02
      • 1970-01-01
      • 2010-09-07
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多