2011-07-12 23 views
9

Cuando uso un MemoryStream para cargar un archivo Cursor de un archivo de recursos, recibo un ArgumentException. Aquí está el código que uso para cargar el cursor:Al leer un Cursor de un archivo de recursos, se lanza una excepción de argumento

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

Pero me sale el error. No tengo idea de lo que está mal, incluso cambié Cursor = myCursor; a this.Cursor = myCursor; que me dio el mismo error. Intenté gameform.Cursor = myCursor; pero eso no funcionó en absoluto.

 
System.ArgumentException: Image format is not valid. The image file may be corrupted. 
Parameter name: stream ---> System.Runtime.InteropServices.COMException (0x800A01E1): Exception from HRESULT: 0x800A01E1 (CTL_E_INVALIDPICTURE) 
    at System.Windows.Forms.UnsafeNativeMethods.IPersistStream.Load(IStream pstm) 
    at System.Windows.Forms.Cursor.LoadPicture(IStream stream) 
    --- End of inner exception stack trace --- 
    at System.Windows.Forms.Cursor.LoadPicture(IStream stream) 
    at WaterforMGC.gameform.Form1_Load(Object sender, EventArgs e) in C:\Users\Jan\Documents\Visual Studio 2008\Projects\WaterforMGC\WaterforMGC\Form1.cs:line 39 
    at System.Windows.Forms.Form.OnLoad(EventArgs e) 
    at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) 
    at System.Windows.Forms.Control.CreateControl() 
    at System.Windows.Forms.Control.WmShowWindow(Message& m) 
    at System.Windows.Forms.Control.WndProc(Message& m) 
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
+0

¿En qué formato de imagen está su imagen? –

+0

mensajes de excepción están allí para ser leídos ... Obviamente no has hecho eso, porque cambiaste cosas en la línea después de aquella que resultó en la excepción para arreglar el error ... –

+0

@Dan: Dudo que él supiera qué él estaba buscando en ese muro gigante de texto de excepción. Lo reduje, espero que ayude. – user7116

Respuesta

11

El problema se deletrea hacia fuera en la primera línea de la excepción:

System.ArgumentException: Formato de imagen no es válido. El archivo de imagen puede estar dañado.

¿Seguro de la imagen que va a cargar está en un estado no corrompido, y es compatible with the image format for cursors?

La clase Cursor no admite cursores animados (archivos .ani) o cursores con colores que no sea blanco y negro.

¿Hay otros lugares donde cargue una imagen de cursor y funciona? Es posible que puedas resolverlo para determinar qué está pasando mal aquí.

+0

Sí, estoy seguro. Estoy usando un archivo .cur para mi cursor. No tengo idea de qué pasa ... Y nunca cargué un cursor en C# – janj

+2

@janj: [por MSDN] (http://msdn.microsoft.com/en-us/library/system.windows.forms. cursor% 28v = VS.80% 29.aspx), "La clase Cursor no admite cursores animados (archivos .ani) ni cursores con colores distintos al blanco y negro". ¿Están animados o coloreados? – user7116

+0

@sixlettervariables Es de color. Entonces eso significaría que no puedo usarlo ... – janj

3

Por alguna razón, la clase de cursor es demasiado exigente con respecto a lo que leerá. Puede crear el manejador usted mismo usando la API de Windows y luego pasarlo a la clase de cursor.

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 
<System.Runtime.InteropServices.DllImport("user32.dll")> 
Private Shared Function LoadCursorFromFile(fileName As String) As IntPtr 
End Function 
6

De hecho que es posible cargar los cursores de color en .Net. Solo necesitas usar win32 hazlo.

[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; 
+1

¿Cómo puedo hacer eso desde una secuencia de memoria? La transmisión proviene del ensamblado.GetManifestResourceStream (... – Pedro77

0

Debido a que tiene el cursor como un recurso del proyecto, se puede hacer esto:

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

Entonces, para obtener el cursor, que acaba de hacer:

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

lectura El cursor desde un archivo a través de un puntero utilizando Win API le permite manejar cursores animados o de color, a pesar de las limitaciones enumeradas en MSDN para la clase Cursor.

Mi respuesta se basó en this another SO answer (y felizmente probado en .NET 4.0).

Cuestiones relacionadas