从资源文件中读取Cursor时,抛出ArgumentException

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

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

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

 System.ArgumentException:图像格式无效。 图像文件可能已损坏。
参数名称:stream ---> System.Runtime.InteropServices.COMException(0x800A01E1):来自HRESULT的exception:0x800A01E1(CTL_E_INVALIDPICTURE)
   在System.Windows.Forms.UnsafeNativeMethods.IPersistStream.Load(IStream pstm)
   在System.Windows.Forms.Cursor.LoadPicture(IStream流)
    ---内部exception堆栈跟踪结束---
   在System.Windows.Forms.Cursor.LoadPicture(IStream流)
    at WaterforMGC.gameform.Form1_Load(Object sender,EventArgs e)在C:\ Users \ Jan \ Documents \ Visual Studio 2008 \ Projects \ WaterforMGC \ WaterforMGC \ Form1.cs:第39行
   在System.Windows.Forms.Form.OnLoad(EventArgs e)
   在System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   在System.Windows.Forms.Control.CreateControl()
   在System.Windows.Forms.Control.WmShowWindow(Message&m)
   在System.Windows.Forms.Control.WndProc(Message&m)
   在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m)
   在System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)

问题在exception的第一行拼写出来:

System.ArgumentException:图像格式无效。 图像文件可能已损坏。

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

Cursor类不支持动画光标 (.ani文件) 或具有黑色和白色以外颜色的光标

你还有其他任何你加载光标图像的地方吗? 你可能能够解决这个问题,以确定这里出了什么问题。

实际上,您可以将彩色光标加载到.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.Net:

 '(in a class)' Public Shared Function ActuallyLoadCursor(path As String) As Cursor Return New Cursor(LoadCursorFromFile(path)) End Function  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上愉快地测试)。