2011-07-12 13 views
9

Kiedy używam MemoryStream do załadowania Cursor z pliku zasobów, otrzymuję ArgumentException. Oto kod, którego używam do ładowania kursora:Podczas odczytywania kursora z pliku zasobów wywoływany jest wyjątek ArgumentException.

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

Ale pojawia się błąd. Nie mam pojęcia, co jest nie tak, zmieniłem nawet Cursor = myCursor; na this.Cursor = myCursor;, co dało mi ten sam błąd. Próbowałem gameform.Cursor = myCursor;, ale to w ogóle nie działało.

 
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

Jakiego formatu zdjęć jest twój obraz? –

+0

komunikaty o wyjątkach są do przeczytania ... Oczywiście tego nie zrobiliście, ponieważ zmieniliście rzeczy w linii po tym, który spowodował wyjątek, aby naprawić błąd ... –

+0

@Dan: Wątpię, że wiedział co szukał w tej gigantycznej ścianie wyjątkowego tekstu. Załatałem to, mam nadzieję, że to pomoże. – user7116

Odpowiedz

11

Problemem jest napisane na pierwszej linii wyjątkiem:

System.ArgumentException: Format obrazu nie jest prawidłowa. Plik obrazu może być uszkodzony.

Czy jesteś pewien, że masz obraz ładowania jest w stanie nieuszkodzonym i jest compatible with the image format for cursors?

Klasa Kursor nie obsługuje Animowane kursory (ANI plików) lub kursorów z kolorami inne niż czarno-białe.

Czy masz inne miejsca, w których ładujesz obraz kursora i to działa? Możesz być w stanie z tego zrezygnować, aby ustalić, co się tutaj dzieje.

+0

Tak, jestem pewien. Używam pliku .cur dla mojego kursora. Nie mam pojęcia, co jest nie tak ... I nigdy nie załadowałem kursora w C# – janj

+2

@janj: [za MSDN] (http://msdn.microsoft.com/en-us/library/system.windows.forms. cursor% 28v = VS.80% 29.aspx), "Klasa Cursor nie obsługuje animowanych kursorów (plików .ani) ani kursorów w kolorach innych niż czarny i biały." Czy są animowane czy kolorowe? – user7116

+0

@sletterlettervariables Jest kolorowy. Oznaczałoby to, że nie mogę go użyć ... – janj

3

Z jakiegoś powodu klasa kursora jest zbyt wybredna w stosunku do tego, co przeczyta. Możesz utworzyć uchwyt samodzielnie za pomocą interfejsu API systemu Windows, a następnie przekazać go do klasy kursora.

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

W rzeczywistości można ładować kolorowe kursory w .NET. Musisz tylko użyć 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; 
+1

Jak mogę to zrobić ze strumienia pamięci? Strumień pochodzi z assembly.GetManifestResourceStream (... – Pedro77

0

Ponieważ masz kursor jako zasób projektu, można to zrobić:

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

Następnie, dla uzyskania kursor, po prostu zrobić:

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

Reading kursor z pliku za pomocą wskaźnika za pomocą interfejsu API Win pozwala obsługiwać animowane lub kolorowe kursory, pomimo ograniczeń wymienionych w MSDN dla klasy kursora.

Moja odpowiedź była oparta na this another SO answer (i szczęśliwie przetestowane na .NET 4.0).

Powiązane problemy