在vb6中"DoEvents“是做什么的?为什么我得到错误信息“超出堆栈空间”?这是什么意思?
发布于 2010-12-24 21:49:14
DoEvents()允许处理其他窗口消息。
出现堆栈空间不足错误的原因可能是因为DoEvents()允许再次调用您的代码的事件发生,它再次调用DoEvents(),依此类推,直到跟踪所有这些调用的返回地址的堆栈空间耗尽。
一般来说,我不推荐使用DoEvents(),因为这样的问题和它违背了Window的整体事件驱动设计。
发布于 2013-05-31 23:18:47
看待DoEvents的另一种略微不同的方式是,它刷新事件队列中的事件。如果您的sub或函数触发了一个事件,则该事件处理程序将成为一个sub,它将在您的sub/function完成后立即运行。DoEvents说现在就运行事件处理器子句柄,而不是等到子句柄结束。
虽然我在精神上同意Jonathon不使用DoEvents,但我会缓和他的声明,说我只推荐使用它,如果您确切地知道为什么,并且知道以这种方式更改事件队列的顺序的所有后果。大多数情况下,在子例程执行完成之前,当您想从子例程的上下文中以某种方式更新屏幕时,会指示DoEvents。
这方面的一个示例是使用ProgressBar控件时。假设您正在迭代数千条记录,并希望通过更新进度条向用户提供有关您的进度的反馈。您可以每隔一百条记录中断一次循环,并更改进度条控件上的值。但是(除非您对此做了些什么),直到进度条的change事件处理程序运行之后,您才会在屏幕上看到更改,并且该处理程序直到您的sub完成执行后才会运行。它将被放入事件队列中。强制更改事件立即运行的方法是调用DoEvents。这将刷新队列中的所有现有事件--在本例中是进度条的更改事件--并将更新屏幕上的进度条控件。
现在,“超出堆栈空间”基本上意味着你陷入了函数调用的无休止循环。最基本的方法是:
Public sub MySub()
MySub
End Sub
然后从某个地方给MySub打电话。你会得到一个超出堆栈空间的错误。如果您查看调用堆栈,您将看到一长串对MySub的调用。
在VB的旧版本中,这是一个众所周知的真实例子:
Public Sub TextBoxArray_LostFocus(index as Integer)
If TextBoxArray(index) = "" Then
TextBoxArray(index).SetFocus
MsgBox "Please enter a value"
End If
End Sub
这种情况假设名为TextBoxArray的TextBox控件数组有两个成员。现在,如果用户从第一个(索引0)开始,移动到第二个(索引1),那么索引0的LostFocus事件将被激发。但是,VB也会在内部将焦点设置到索引1框。然后,代码将焦点设置回索引0,激发索引1的LostFocus事件!你陷入了一个循环。他们在VB5或6中修复了这一问题,方法是等到LostFocus事件执行完毕后才设置焦点。
发布于 2010-12-28 01:36:27
我想澄清Johnathon的答案,它泵送VB消息循环,并允许VB运行时处理windows消息,这与睡眠相反,睡眠允许Windows处理其事件(在多核CPU和真正的多任务操作系统的世界中,不是必需的,但当VB6被编写时,Windows9x是占主导地位的操作系统,一个只有DoEvents的硬循环会使CPU使用率达到100%)。所以看到像这样的东西
While fDoneFile = False
DoEvents
Sleep 55
Wend
是整个VB6世界中的一种常见模式。
https://stackoverflow.com/questions/4526659
复制相似问题