在WPF中设置自定义光标映像热点 [英] Set Custom Cursor Image Hotspot in WPF

查看:252
本文介绍了在WPF中设置自定义光标映像热点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Cursor上使用自定义图像,我使用这些代码。

I am trying to use custom images on Cursor and I did it with these code.

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);
    }

}

p>

And using in code is

    private void btnVerticalMullion_Click(object sender, RoutedEventArgs e)
    {
        this.Cursor = cursorHelper.vertical;
    }

我的问题是光标的热点是左下点。我需要将其更改为图像的0,0(左上)点。任何身体可以帮助我吗?
提前感谢,

My problem is the hotspot of the Cursor is bottom-left point. I need to change it to 0,0 (top-left) point of the image. Can any body help me please? Thanks in advance,

推荐答案

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

It's because you are using .ICO files instead of .CUR files as the data to the Cursor class.

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

While the .ICO and .CUR file formats are similar, the .ICO format doesn't contain the hotspot info.

  • http://en.wikipedia.org/wiki/ICO_(file_format)#cite_note-11

您有两个选择:


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


    使用您可以在网络上找到的转换实用程序,

    在Visual Studio中创建新的.CUR文件,然后复制并粘贴来自.ICO文件的数据。

  • convert your .ICO files to .CUR files and embed those as resources instead

    Do that by using a conversion utility which you can find on the web,
    or
    create a new .CUR file in Visual Studio and then copy and paste the data from your .ICO files.

将它们保存为.ICO文件,但是当传递给Cursor类时,它会破坏CUR格式的数据。

keep them as .ICO files but hack the data so it follows the CUR format when passed to the Cursor class.

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

Here's some example code to modify the ICO stream to turn it into the CUR format.

在本例中,我使用ICO文件其中包含一个单一的32X32X4位BMP图像,我想让光标有一个(15,15)热点。

In this example I tested it with an ICO file which contained a single 32X32X4bit BMP image, and I wanted the cursor to have a (15,15) hotspot.

这段代码只是让你开始,如果你下去这个路由...它需要更多的代码来处理错误,以及处理ICO文件包含多个图标图像(即如果多个条目)等。

This code is just to get you started if you go down this route...it needs more code to handle errors, and the ability to deal with ICO files that contain multiple icon images (i.e. if multiple entries), etc.

您还可以使用 BinaryWriter 更自然地处理数据。使用 Write(UInt16),写出使用2个字节(即超过255)的热点坐标。

You could also use a BinaryWriter to more naturally handle the data e.g. for writing out hotspots coords that use 2 bytes (i.e. over 255) by using Write(UInt16).

img src =https://i.stack.imgur.com/AbwjY.pngalt =输入图片说明here>>

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>

这篇关于在WPF中设置自定义光标映像热点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆