При чтении курсора из файла ресурсов выдается исключение ArgumentException - PullRequest
9 голосов
/ 12 июля 2011

Когда я использую MemoryStream для загрузки Cursor из файла ресурсов, я получаю ArgumentException. Вот код, который я использую для загрузки курсора:

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

Но я получаю ошибку. Я понятия не имею, что не так, я даже изменил Cursor = myCursor; на this.Cursor = myCursor;, который дал мне ту же ошибку. Я пытался gameform.Cursor = myCursor;, но это совсем не сработало.

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)

Ответы [ 4 ]

11 голосов
/ 12 июля 2011

Проблема прописана в самой первой строке исключения:

System.ArgumentException: формат изображения недопустим. Файл изображения может быть поврежден.

Вы уверены, что загружаемое изображение не повреждено и совместимо с форматом изображения для курсоров?

Класс Cursor не поддерживает анимированные курсоры (файлы .ani) или курсоры с цветами, отличными от черного и белого .

Есть ли у вас другие места, где вы загружаете изображение курсора, и оно работает? Возможно, вам удастся отработать это, чтобы определить, что здесь происходит не так.

6 голосов
/ 09 апреля 2012

На самом деле вы можете загрузить цветные курсоры в .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;
3 голосов
/ 18 октября 2011

По какой-то причине класс курсора слишком требователен к тому, что он будет читать.Вы можете создать дескриптор самостоятельно, используя 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
<System.Runtime.InteropServices.DllImport("user32.dll")>
Private Shared Function LoadCursorFromFile(fileName As String) As IntPtr
End Function
0 голосов
/ 16 ноября 2013

Поскольку у вас есть курсор в качестве ресурса проекта, вы можете сделать это:

[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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...