У меня проблема с пользовательскими курсорами в приложении WPF.Я использую следующий код для создания объектов Cursor
:
[DllImport("user32.dll")]
private static extern IntPtr CreateIconIndirect(ref IconInfo icon);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
private static Cursor CreateCursor(string cursorName, System.Drawing.Bitmap bmp,
int xHotspot, int yHotspot, out SafeFileHandle handle)
{
IconInfo tmp = new IconInfo();
GetIconInfo(bmp.GetHicon(), ref tmp);
tmp.xHotspot = xHotspot;
tmp.yHotspot = yHotspot;
tmp.fIcon = false;
IntPtr ptr = CreateIconIndirect(ref tmp);
handle = new SafeFileHandle(ptr, true);
if (handle.IsClosed)
{
return null;
}
Cursor cur = CursorInteropHelper.Create(handle);
return cur;
}
Когда я закрываю свое приложение, и GC начинает собирать мусор, оно выдает исключение:
System.Runtime.InteropServices.SEHException was unhandled
Message=External component has thrown an exception.
Source=mscorlib
ErrorCode=-2147467259
StackTrace:
at Microsoft.Win32.Win32Native.CloseHandle(IntPtr handle)
at Microsoft.Win32.SafeHandles.SafeFileHandle.ReleaseHandle()
at System.Runtime.InteropServices.SafeHandle.InternalDispose()
at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)
at System.Runtime.InteropServices.SafeHandle.Dispose()
at System.Windows.Input.Cursor.Finalize()
InnerException:
Iпровел дальнейшее расследование, установив точку останова на if (handle.IsClosed)
и используя непосредственное окно для вызова handle.Close()
.Некоторые из SafeFileHandle
закрываются очень хорошо, другие выдают то же исключение - сразу после создания дескриптора.
И просто, чтобы сделать забавные вещи, сами ручки работают просто отлично.IsInvalid
ложно, IsClosed
ложно, и появляются курсоры.Просто некоторые дескрипторы никогда не могут быть закрыты.
Поскольку я никогда не собираюсь закрывать дескрипторы вручную, и они будут закрываться только во время финализации объектов Cursor
при закрытии приложения, я мог бы бытьвозможность просто игнорировать их.Я не пробовал сборку Release вне VS2010, и я не знаю, приведет ли это к появлению диалогового окна сбоя.Но даже если я могу игнорировать их, это все еще грязно.
Так что в основном я ищу любую информацию о том, что может пойти не так, где искать, чтобы попытаться отладить это ... все кажетсяв нативном коде или GC, и я не могу отладить ничего из этого.