问题描述
我在与在WPF应用程序自定义光标一个问题。我用下面的代码来创建光标
对象:
I'm having a problem with custom cursors in a WPF application. I use the following code to create the Cursor
objects:
[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开始拿起垃圾桶,它抛出一个例外:
When I close my application and GC starts picking up the trash, it throws an exception:
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:
我没有通过放置如果(handle.IsClosed)
断点,并使用即时窗口调用 handle.Close一些进一步的调查( )
。有些 SafeFileHandle
的亲密就好,别人抛出同样的异常—后,立即把手已创建。
I did some further investigation by placing a breakpoint on if (handle.IsClosed)
and using the immediate window to call handle.Close()
. Some of the SafeFileHandle
's close just fine, others throw the same exception — immediately after the handle was created.
而只是为了让事情有趣,在处理自己的工作就好了。 IsInvalid
为假, isClosed返
是假的,光标出现。这只是一些把手不能被关闭。
And just to make things fun, the handles themselves work just fine. IsInvalid
is false, IsClosed
is false, and the cursors appear. It's just that some of the handles can never be closed.
由于我从来没有打算手动关闭句柄,他们将只在<$ C定稿过程中被关闭$ C>光标对象的应用程序关闭时,我也许可以不理会他们。我没有试过一个发布版本外VS2010,我不知道这是否会导致出现崩溃对话框。但是,即使我可以忽略它们,它仍然是混乱的。
As I never intend to close the handles manually, and they will only be closed during finalization of the Cursor
objects when the application closes, I might be able to just ignore them. I haven't tried a Release build outside VS2010 and I don't know if that will cause a crash dialog to appear. But even if I can ignore them, it's still messy.
所以基本上我在寻找什么可能会在这里走错了,在这里任何信息看,试图这个调试......一切似乎都在本机代码或GC,我不能调试任何它。
So basically I'm looking for any info on what might be going wrong here, where to look to try and debug this... everything seems to be in native code or GC and I can't debug any of it.
推荐答案
您'重新包装的惠康
从 CreateIconIndirect
在返回 SafeFileHandle
其中,在释放,来电 CloseHandle的
上的惠康
而不是所需要的 DestroyIcon
。不裹惠康
在 SafeFileHandle
,而是在自己的专业的SafeHandle
:
You're wrapping the HICON
returned from CreateIconIndirect
in a SafeFileHandle
which, on releasing, calls CloseHandle
on the HICON
instead of the needed DestroyIcon
. Don't wrap HICON
in SafeFileHandle
but instead in an own, specialized SafeHandle
:
class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DestroyIcon(
[In] IntPtr hIcon);
private SafeIconHandle()
: base(true)
{
}
public SafeIconHandle(IntPtr hIcon)
: base(true)
{
this.SetHandle(hIcon);
}
protected override bool ReleaseHandle()
{
return DestroyIcon(this.handle);
}
}
这篇关于SafeFileHandle.Close抛出一个异常,但手柄是有效的,作品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!