1

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 (左上) ポイントに変更する必要があります。どんな体でも私を助けてくれますか?前もって感謝します、

4

1 に答える 1

4

Cursorこれは、クラスへのデータとして .CUR ファイルではなく .ICO ファイルを使用しているためです。

.ICO と .CUR ファイル形式は似ていますが、.ICO 形式にはホットスポット情報が含まれていません。

次の 2 つの選択肢があります。

  • .ICO ファイルを .CUR ファイルに変換し、代わりにそれらをリソースとして埋め込む

    Web 上にある変換ユーティリティを使用する

    、Visual Studio で新しい .CUR ファイルを作成し、. ICO ファイル。

  • それらを.ICOファイルとして保持しますが、データをハックして、Cursorクラスに渡されるときにCUR形式に従います。

ICO ストリームを変更して CUR 形式に変換するサンプル コードを次に示します。

この例では、単一の 32X32X4bit BMP イメージを含む ICO ファイルでテストし、カーソルに (15,15) ホットスポットを持たせたいと考えました。

このコードは、このルートをたどる場合に開始するためのものです...エラーを処理するためのコードがさらに必要であり、複数のアイコン画像を含む (つまり、複数のエントリの場合) ICO ファイルを処理する機能などが必要です。

BinaryWriterまた、を使用して 2 バイト (つまり 255 以上) を使用するホットスポット座標を書き出すなど、データをより自然に処理するために を使用することもできますWrite(UInt16)

ここに画像の説明を入力

ここに画像の説明を入力

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>
于 2012-09-16T17:36:45.067 に答える