【发布时间】:2012-06-14 16:46:28
【问题描述】:
我有一个有计时器问题的旧 VB6 应用程序。有一个模态表单,其中包含一些元素和两个计时器(VB6 标准计时器)。每个定时器都是这样工作的(伪代码):
-- TimerEvent Start
DoSomething
DoEvents
-- TimerEvent End
然后,在某个时间点,会引发来自 OCX 控件的某个连接丢失的事件。与计时器本身无关。但是此时,两个计时器都不再引发计时器事件,尽管 - 现在很奇怪 - 计时器已启用并设置了 2000 的间隔。即使重新启用和重新设置间隔也没有任何效果。当来自同一 OCX 控件的另一个事件引发连接已恢复时,计时器事件会突然再次引发。 即使删除 OCX 控件事件处理程序中的所有代码,计时器也不起作用。
我对 DoEvents “模式”不是很熟悉,但我认为问题一定与 DoEvents 有关。删除它并没有改变任何东西。
有人知道这里会发生什么吗?我已经在寻找任何可以阻止计时器引发已逝事件的全局设置,但看在上帝的份上,我找不到任何设置。
我要疯了……
感谢您的帮助。
【问题讨论】:
-
我非常怀疑问题出在您引用的代码中。相反,我怀疑 OCX 控件是用 C/C++ 编写的,并且直接与应用程序的消息泵混淆,从而破坏了你的计时器。
-
已经有一段时间了,但是 DoEvents 基本上是在您长时间阻塞主线程时清空事件队列。我不确定它的确切效果 - 我知道在某些情况下,连续多次调用 DoEvents 是必要的。它的主要用途是在执行更长时间的处理时继续绘制 UI 并响应用户输入。我不确定您为什么要在事件处理程序的 END 调用它,但我认为它实际上不会在那里产生任何影响。
-
您的问题可能归结为 OCX 在某处调用
GetMessage()并消耗了您的计时器事件。我怀疑,但不确定,VB6 定时器只是在下面使用 WM_TIMER。也许OCX,听起来像是一个网络库,内部使用了一个WM_TIMER作为它的超时,并且错误地将VB6定时器的消息解释为它自己的超时消息。 -
我已经有一段时间没有接触 VB6 了,但通常你不会把自己弄得一团糟——它几乎总是一个外部 C 库。祝你好运!
-
计时器确实在幕后使用了 WM_TIMER,我想这些消息可能会被消耗掉。调用 DoEvents 获取并分派当前线程的 windows 消息队列中的任何消息,直到它为空。应该避免它,因为它会导致重入问题。