当从资源文件中读取游标时,会抛出ArgumentException

本文关键字:ArgumentException 游标 资源 源文件 读取 | 更新日期: 2023-09-27 18:02:05

当我使用MemoryStream从资源文件加载Cursor时,我收到ArgumentException。下面是我用来加载游标的代码:

Cursor myCursor
    = new Cursor(new MemoryStream(WaterforMGC.Properties.Resources.waterspray));
Cursor = myCursor;

但是我得到了错误。我不知道什么是错的,我甚至把Cursor = myCursor;改为this.Cursor = myCursor;,这给了我同样的错误。我试过gameform.Cursor = myCursor;,但根本不起作用。

<>之前系统。图片格式无效。镜像文件可能已损坏。参数名称:stream --> System.Runtime.InteropServices.COMException (0x800A01E1): Exception from HRESULT: 0x800A01E1 (ctle_invalidpicture)在System.Windows.Forms.UnsafeNativeMethods.IPersistStream。加载(IStream pstm)在System.Windows.Forms.Cursor。LoadPicture (IStream流)——内部异常堆栈跟踪结束——在System.Windows.Forms.Cursor。LoadPicture (IStream流)在WaterforMGC.gameform。在c:' users ' jane ' documents ' visual Studio 2008'Projects'WaterforMGC'WaterforMGC' form .cs中加载(对象发送方,EventArgs e):第39行在System.Windows.Forms.Form。OnLoad (EventArgs e)在System.Windows.Forms.Control。CreateControl(布尔fIgnoreVisible)在System.Windows.Forms.Control.CreateControl ()在System.Windows.Forms.Control。WmShowWindow(消息)在System.Windows.Forms.Control。指向(消息)在System.Windows.Forms.Control.ControlNativeWindow。指向(消息)在System.Windows.Forms.NativeWindow。回调(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

当从资源文件中读取游标时,会抛出ArgumentException

异常的第一行就详细说明了问题:

系统。图片格式无效。镜像文件

您确定正在加载的图像处于未损坏状态,并且与光标的图像格式兼容吗?

Cursor类不支持动画游标(。(任何文件)或使用非黑色和白色的光标

你还有其他地方可以加载光标图像吗?你也许可以从中找出问题所在

事实上,您可以将彩色光标加载到。net中。你只需要使用win32就可以了。

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr LoadImage(IntPtr hinst, string lpszName, uint uType, int cxDesired, int cyDesired, uint fuLoad);
//........
const int IMAGE_CURSOR = 2; 
const uint LR_LOADFROMFILE = 0x00000010;
IntPtr ipImage = LoadImage(IntPtr.Zero, 
    @"c:'mycolor.cur", 
    IMAGE_CURSOR, 
    0, 
    0, 
    LR_LOADFROMFILE);
Cursor testCursor = new Cursor(ipImage);
Cursor.Current = testCursor;

由于某些原因,游标类对要读取的内容太挑剔了。您可以使用windows API自己创建句柄,然后将其传递给游标类。

c#:

//(in a class)
public static Cursor ActuallyLoadCursor(String path) {
    return new Cursor(LoadCursorFromFile(path))
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr LoadCursorFromFile(string fileName);

VB。净:

'(in a class)'
Public Shared Function ActuallyLoadCursor(path As String) As Cursor
    Return New Cursor(LoadCursorFromFile(path))
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")>
Private Shared Function LoadCursorFromFile(fileName As String) As IntPtr
End Function

因为您有游标作为项目的资源,所以您可以这样做:

[DllImport("User32.dll", CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
private static extern IntPtr LoadCursorFromFile(String str);
public static Cursor LoadCursorFromResource(Icon icono)  // Assuming that the resource is an Icon, but also could be a Image or a Bitmap
{
    // Saving cursor icon in temp file, necessary for loading through Win API
    string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".cur";
    using (var fileStream = File.Open(fileName, FileMode.Create))
    {
        icono.Save(fileStream);
    }
    // Loading cursor from temp file, using Win API
    Cursor result = new Cursor(LoadCursorFromFile(fileName));
    // Deleting temp file
    File.Delete(fileName);
    return result;
}

然后,要获取光标,只需执行:

Cursor myCursor = LoadCursorFromResource(WaterforMGC.Properties.Resources.waterspray);

使用Win API通过指针从文件中读取光标,允许您处理动画或彩色光标,尽管在MSDN中列出了cursor类的限制。

我的答案是基于另一个SO的答案(并愉快地在。net 4.0上测试)。