0

我正在使用类似于这个问题的公认答案的代码来制作自定义光标。我想我可以问,“当我用完自定义光标后该怎么办?” 但具体来说,我的问题有两个部分:

一:我看到使用反射设置光标的“ownHandle”字段的代码。这是否会使(本机)句柄在 Cursor 对象被释放时被破坏?如果不是,它有什么作用?

二:我必须手动处置光标对象还是将新光标分配给控件会导致控件为我处置光标?例如:

private void customCursorButton_Clicked(object sender, EventArgs e)
{
    this.Cursor = NativeMethods.LoadCustomCursor(@"c:\windows\cursors\aero_busy.ani");
}

private void defaultCursorButton_Clicked(object sender, EventArgs e)
{
    var tmp = this.Cursor; // do I have to do this
    this.Cursor = Cursors.Default;
    tmp.Dispose();         // and this?
}
4

2 回答 2

6

如果您 100% 确定该对象不会在其他任何地方使用,则您应该只在对象上调用 Dispose()。调用 Dispose() 是可选的,对象的终结器可确保始终进行清理。并且 100% 确定它不会在其他任何地方使用。做这项工作只是有点慢。

单个游标对象没有什么意义,一个游标最多只有几千字节的内存。但是您的代码会为每次点击一遍又一遍地创建光标,并且可能会处理不会赢得很多奖品的父光标(Cursor 属性是环境属性)。因此,做出努力的正确代码应该类似于:

private Cursor CustomCursor;

private void customCursorButton_Clicked(object sender, EventArgs e)
{
    if (CustomCursor == null) CustomCursor = NativeMethods.LoadCustomCursor(@"c:\windows\cursors\aero_busy.ani");
    this.Cursor = CustomCursor;
}

private void defaultCursorButton_Clicked(object sender, EventArgs e)
{
    var prev = this.Cursor;
    this.Cursor = Cursors.Default;
    if (prev == CustomCursor) {
        CustomCursor.Dispose();
        CustomCursor = null;
    }
}

protected override OnFormClosed(FormClosedEventArgs e) 
{
    base.OnFormClosed(e);
    if (CustomCursor != null) CustomCursor.Dispose();
}

有一个简单的诊断可以知道你弄错了顺便说一句。任务管理器通常不太适合分析 .NET 应用程序,但它可以很好地向您展示在这种情况下缺少 Dispose() 调用是否会给您带来麻烦。使用 View + Select Columns 并勾选“GDI Objects”,它非常准确地跟踪光标对象(除了其他 GDI 对象)。让显示的值超过几百是麻烦的标志,给予或接受。

请注意,您必须使用 Environment.GetFolderPath() 来检索 Windows 的安装位置。并且处理失败,并不能保证光标始终可用。细节,细节。

于 2014-06-26T21:39:08.447 回答
1

应该处置您正在创建的对象,并且您的做法似乎很好。

只是不要忘记在表单关闭时处理您的自定义光标。

我看到使用反射设置光标的“ownHandle”字段的代码。这是否会使(本机)句柄在 Cursor 对象被释放时被破坏?如果不是,它有什么作用?

它应该释放手柄。Disposing旨在释放非托管资源。

我是否必须手动处置光标对象,或者将新光标分配给控件是否会导致控件为我处置光标?

丢失对包含非托管资源的对象的引用是一个坏主意。它最终将被 GC'ed 并调用 desctuctor 来处理对象,但仍然如此。

然而,重新分配财产Cursor是另一回事。可能会创建属性的设置器来自行处理旧值,但是,我有一种强烈的感觉,它不会那样做。

于 2014-06-26T21:27:08.680 回答