首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Win32Exception -创建窗口句柄错误?

Win32Exception -创建窗口句柄错误?
EN

Stack Overflow用户
提问于 2013-06-06 06:36:40
回答 3查看 4.5K关注 0票数 1

你能解释一下为什么会发生这种事吗?下面是重现异常的步骤:

  1. 将TextBox拖放到窗体上.添加任何其他可聚焦控件,如窗体上的按钮。
  2. 为该TextBox添加2个事件处理程序,如下所示: 私有void textBox_GotFocus(对象发送方,EventArgs e){ ((TextBox)发送方).HideSelection= false;//<--此处突出显示的异常。}私有空textBox_LostFocus(对象发送方,EventArgs e){ ((TextBox)发送方).HideSelection= true;}
  3. 运行表单,首先单击textBox,然后单击按钮,然后再次单击textBox,异常将抛出:“创建Win32Exception错误窗口句柄”。

代码只是在HideSelection聚焦而失去焦点时使textBox相应地改变。

更新

我不知道为什么这么不稳定,我创建了另一个项目,现在问题不一样了,没有例外,只有一个不确定的循环,使文本框闪烁,表单似乎没有响应,CPU使用率高达17%-20%。最后一个演示仍然是打开的,而且该演示仍然抛出了Win32Exception。一点线索都没有。现在这两个项目的代码是相同的,但问题是不同的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-06 07:12:24

嗯,有几件事要注意。

首先,HideSelection不隐藏或取消隐藏所选内容。它指定控件失去焦点时是否隐藏所选内容。因此,当TextBox成为焦点时,改变它是没有意义的。

您在LostFocus中所做的是默认的,顺便说一句。我想,为什么GotFocus中有一个异常被埋在Windows中。当HideSelection检查焦点内部的某个未定义状态时,可能会更改事件,无论TextBox是否有焦点,或者试图隐藏未显示的选择。编辑:这不是第一手的Windows,而是框架。它试图在HideSelection的设置器中“重新创建句柄”,如果它被更改(还不知道为什么--必须分析源),并且似乎失败了(也不知道为什么)。Edit2:最后,Win32 DestroyWindow中存在一些问题--这会导致跳过新窗口的创建。也许是因为旧的“正在使用”的焦点改变事件?

有趣的是,一旦异常发生(对我来说),就会触发LostFocus事件,紧接着是引发另一个异常a.s.o的GotFocus。这样就阻塞了GUI。两个分配给HideSelection的任务都会引发异常。

此外,当您单击TextBox时,任何选择都会自动取消。但是,这不是问题的原因,因为如果通过按Tab更改焦点(其正常行为是恢复焦点),则会引发异常。但这可能是相关的(国家问题)。

如果您真的想恢复所选内容,您可以这样做:

代码语言:javascript
复制
int selStart;
int selLen;
void textBox1_LostFocus(object sender, EventArgs e)
{
    selStart = textBox1.SelectionStart;
    selLen = textBox1.SelectionLength;
}
void textBox1_GotFocus(object sender, EventArgs e)
{
    BeginInvoke((Action)(() =>
    {
       textBox1.SelectionStart = selStart;
       textBox1.SelectionLength = selLen;
    }));
}
票数 2
EN

Stack Overflow用户

发布于 2013-06-06 08:07:04

我复制了这次坠机。通过在事件处理程序上设置断点,您可以很容易地看到它出错,请注意它们是如何在程序爆炸之前一次又一次地发射的。这个解释有点长,我先给出一个简短的版本。MSDN文档为LostFocus事件发出了严厉的警告,既警告也警告,指出这是一个低级别的事件,是危险的。因此,这些事件也隐藏在“属性”窗口中。使用Enter和Leave事件来修复您的问题。

长版本: TextBox.HideSelection属性非常特殊。它与本机Windows控件上某些属性的指定方式有关。这些控件是用CreateWindowEx() winapi函数创建的,它使用一个dwExStyle和dwStyle参数,标志指定窗口的样式选项。HideSelection属性就是这样一个样式标志,ES_NOHIDESEL。

当您想要更改属性时,就会出现问题。困难,因为它只能在创建本机控件时指定。Winforms做了一些非常英勇的事情来解决这个限制,它破坏了本机控制并重新创建了它。

这可能会有相当有趣的副作用,可以温和地说。大多数都是不可观察的,但您确实可以看到屏幕上的窗口被破坏和重新创建。这就是它闪烁的原因。您的代码的核心问题不可避免地是,因为本机窗口正在被破坏,它也失去了焦点。因此,LostFocus事件会立即触发,就在您得到GotFocus事件之后。这做了一些不幸的事情,它再次改变了HideSelection属性。这迫使Winforms再次重新创建本机控件。

当您的GotFocus事件处理程序再次为新的本机控件运行时,这会一次又一次地重复。这最终会在Windows停止并且不允许创建更多的本机窗口时结束,一段时间后,它会在10,000个控件上拔出插头。它生成“创建窗口句柄错误”异常。

输入和离开事件应该始终用于聚焦事件,只有当用户实际移动焦点时才会触发,并且由于其他原因而不触发,比如这个原因。另外值得注意的是,像您这样更改HideSelection属性是没有意义的,只有当TextBox没有焦点时,属性才会产生影响。当选择有焦点时,它永远不会被隐藏。因此,正确的修复方法是删除这些事件处理程序,并将属性窗口中的HideSelection属性设置为True。默认值。

票数 2
EN

Stack Overflow用户

发布于 2013-06-06 07:09:52

不能为我复制这幅作品:

代码语言:javascript
复制
private void textBox1_Leave(object sender, EventArgs e)
{
    ((TextBox)sender).HideSelection = false;
}

private void textBox1_Enter(object sender, EventArgs e)
{
    ((TextBox)sender).HideSelection = true;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16955270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档