C#:如何从资源文件加载Cursor?

时间:2011-08-01 10:41:09

标签: c# .net

我已将文件“x.ani”导入资源文件Resources.resx。现在尝试使用ResourceManager.GetObject(“aero_busy.ani”)

加载该文件
Cursor.Current = (Cursor)ResourcesX.GetObject("aero_busy.ani");

但它不起作用..(当然):)

如何使用资源对象更改当前Cursor?

7 个答案:

答案 0 :(得分:18)

我是通过将光标.cur文件添加到项目的Resources部分(我正在使用Visual Studio)来实现的。我不确定它是否必须是.cur,只要开发程序可以加载它。

在我的代码的变量声明部分完成后,我从游标文件中创建了一个MemoryStream:

private static System.IO.MemoryStream cursorMemoryStream = new System.IO.MemoryStream(myCurrentProject.Properties.Resources.myCursorFile);

...然后你可以从MemoryStream创建游标:

private Cursor newCursor = new Cursor(cursorMemoryStream);

然后,您可以在程序中根据需要指定光标,例如

pictureBox1.Cursor = newCursor;

并且新游标被编译为程序的一部分。

答案 1 :(得分:7)

我没有找到比转储到临时文件更好的方法,并使用文件方法中的Win32加载游标。黑客行为是这样的(为了清楚起见,我删除了一大块样板代码,其中使用流中的数据写入临时文件)。此外,所有异常处理等都已删除。

[DllImport("User32.dll", CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
private static extern IntPtr LoadCursorFromFile(String str);

public static Cursor LoadCursorFromResource(string resourceName)
{         
     Stream cursorStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);        

     // Write a temp file here with the data in cursorStream

     Cursor result = new Cursor(LoadCursorFromFile(tempFile));
     File.Delete(tempFile);

     return result.
}

您可以将其用作(在加载嵌入资源时记住命名空间)。

Cursors.Current = LoadCursorFromResource("My.Namespace.Filename");

答案 2 :(得分:4)

经过几次转向问题后,我发现优雅的解决方案是:

internal static Cursor GetCursor(string cursorName)
    {
        var buffer = Properties.Resources.ResourceManager.GetObject(cursorName) as byte[];

        using (var m = new MemoryStream(buffer))
        {
            return new Cursor(m);
        }
    }

答案 3 :(得分:3)

我认为这个问题与游标必须有.cur扩展名以便用作Cursor这一事实有关。

//以下内容从嵌入式资源生成游标。

//要添加自定义光标,请创建或使用现有的16x16位图 // 1.将新的光标文件添加到项目中: // File-> Add New Item-> Local Project Items-> Cursor File // 2.选择16x16图像类型: // Image->当前图标图像类型 - > 16x16

上述内容取自MSDN

更新:找到答案原因。

“注意事项

Cursor类不支持动画光标(.ani文件)或光标以及黑色和白色以外的光标。“

找到Here

答案 4 :(得分:1)

将文件写入磁盘,然后将其作为光标导入是不切实际的,这是更简单的解决方案。将您的.cur转换为.ico并将您的光标作为图标资源导入。然后,您可以简单地执行以下操作:

Cursor c = new Cursor(Properties.Resources.mycursor.Handle);

这将正确支持32位颜色。

答案 5 :(得分:0)

将它们全部拉在一起...

这是Visual Studio现在提供的强类型资源以及Win32 LoadCursorFromFile(通过使用清单资源加载的Anders original answer)的组合。

我还放入了实例化游标的缓存,因为它适合我的应用程序。否,如果不需要的话。

namespace Draw
{
/// <summary>
/// Controls use of all the cursors in the app, supports loading from strongly typed resources, and caches all references for the lifetime of the app.
/// </summary>
public static class Cursors
{
    // Cache of already loaded cursors
    private static ConcurrentDictionary<byte[], Cursor> cache = new ConcurrentDictionary<byte[], Cursor>();

    /// <summary>
    /// Returns a cursor given the appropriate id from Resources.Designer.cs (auto-generated from Resources.resx). All cursors are
    /// cached, so do not Dispose of the cursor returned from this function.
    /// </summary>
    /// <param name="cursorResource">The resource of the cursor to load. e.g. Properties.Resources.MyCursor (or byte array from .cur or .ani file)</param>
    /// <returns>The cursor. Do not Dispose this returned cursor as it is cached for the app's lifetime.</returns>
    public static Cursor GetCursor(byte[] cursorResource)
    {
        // Have we already loaded this cursor? Use that.
        if (cache.TryGetValue(cursorResource, out Cursor cursor))
            return cursor;

        // Get a temporary file
        var tmpFile = Utils.GetTempFile();

        try
        {
            // Write the cursor resource to temp file
            File.WriteAllBytes(tmpFile, cursorResource);

            // Read back in from temp file as a cursor. Unlike Cursor(MemoryStream(byte[])) constructor, 
            // the Cursor(Int32 handle) version deals correctly with all cursor types.
            cursor = new Cursor(Win32.LoadCursorFromFile(tmpFile));

            // Update dictionary and return
            cache.AddOrUpdate(cursorResource, cursor, (key, old) => cursor);
            return cursor;
        }
        finally
        {
            // Remove the temp file
            Utils.TryDeleteFile(tmpFile);
        }
    }
}
}

示例调用:

Cursor = Draw.Cursors.GetCursor(Properties.Resources.Cursor_ArrowBoundary);

答案 6 :(得分:-1)

    [DllImport("User32.dll")]
    private static extern IntPtr LoadCursorFromFile(string str);

    Cursor SetCursor(byte[] resourceName)
    {
        string tempPath = @"C:\Users\Public\Documents\temp.cur";
        File.WriteAllBytes(tempPath, resourceName);
        Cursor result = new Cursor(LoadCursorFromFile(tempPath));
        File.Delete(tempPath);
        return result;
    }