在VB语⾔中,DOEVENTS的具体的⽤法和含义
DoEvents的应⽤及注意事项
转让控制权,以便让操作系统处理其它的事件。
DoEvents 函数会返回⼀个 Integer,以代表 Visual Basic 独⽴版本中打开的窗体数⽬,例如,Visual Basic,专业版,在其它的应⽤程序中,DoEvents 返回 0。
DoEvents 会将控制权传给操作系统。当操作系统处理完队列中的事件,并且在 SendKeys 队列中的所有键也都已送出之后,返回控制权。
DoEvents 对于简化诸如允许⽤户取消⼀个已启动的过程 — 例如搜寻⼀个⽂件 — 特别有⽤。对于长时间过程,放弃控制权最好使⽤定时器或通过委派任务给 ActiveX EXE 部件来完成。以后,任务还是完全独⽴于应⽤程序,多任务及时间⽚由操作系统来处理。
⼩⼼ 确保以 DoEvents 放弃控制权的过程,在第⼀次 DoEvents 返回之前,不能再次被其他部分的代码调⽤;否则会产⽣不可预料的结果。此外,如果其它的应⽤程序可能会和本过程以不可预知的⽅式进⾏交互操作,那么也不要使⽤ DoEvents,因为此时不能放弃控制权。
使⽤ DoEvents
尽管 Timer 事件是后台处理的最好⼯具,对耗时极多的任务,情况更是如此,但是,DoEvents 函数还是提供了⼀种取消任务的简便⽅法。例如,下列代码将显⽰⼀个 "Process" 按钮,单击这个按钮时,它将变成 "Cancel" 按钮。再次单击按钮⼜将中断正在执⾏的任务。
'此按钮标题是 "Process"
Private Sub Command1_Click()
'过程的所有实例都共享静态变量。
Static blnProcessing As Boolean
Dim lngCt As Long
Dim intYieldCt As Integer
Dim dblDummy As Double
'按下按钮时,检测是否在处理
If blnProcessing Then
'如果正在处理,则取消
blnProcessing = False
Else
Command1.Caption = "Cancel"
blnProcessing = True
lngCt = 0
'执⾏⼀百万次浮点乘法计算。每⼀千次后,检测是否要取消。
Do While blnProcessing And (lngCt < 1000000)
For intYieldCt = 1 To 1000
lngCt = lngCt + 1
dblDummy = lngCt * 3.14159
Next intYieldCt
array在vb什么意思啊'DoEvents 语句允许其它事件发⽣,包括第⼆次按此按钮。
DoEvents
Loop
blnProcessing = False
Command1.Caption = "Process"
MsgBox lngCt & " multiplications were performed"
End If
End Sub
DoEvents 将控制切换到操作环境内核。只要此环境中的所有应⽤程序都有机会响应待处理事件,应⽤程序就⼜恢复控制。这不会使应⽤程序放弃焦点,但会使后台事件能够得到处理。
这种妥协的结果可能并不总是达到预期⽬标。例如,下述 Click 事件代码在单击按钮后要⼀直等候⼗秒钟,⽽后才显⽰⼀条信息。如果在按
钮正在等待期间单击它,则将以相反顺序完成单击操作。
Private Sub Command2_Click()
Static intClick As Integer
Dim intClickNumber As Integer
Dim dblEndTime As Double
'每次单击按钮时
'赋予唯⼀数值。
intClick = intClick + 1
intClickNumber = intClick
'等待⼗秒。
dblEndTime = Timer + 10#
Do While dblEndTime > Timer
'不做任何事情,仅仅允许
'其它应⽤程序处理
'它们的事件。
DoEvents
Loop
MsgBox "Click " & intClickNumber & " is finished"
End Sub
对于通过 DoEvents 放弃控制的事件过程,有时可能希望防⽌在 DoEvents 返回之前重新调⽤这⼀过程。否则将⽆穷⽆尽地调⽤该过程,直到系统资源消耗殆尽。可暂时禁⽌控件,或象上例⼀样,使⽤⼀个静态的“标志”变量防⽌此事发⽣。
在使⽤全局数据时避免 DoEvents
当⼀个函数已通过 DoEvents 放弃控制时,可相当安全地再次调⽤函数。例如,下⼀过程将检测质数并⽤ DoEvents 语句周期地启动其它应⽤程序处理事件:
Function PrimeStatus (TestVal As Long) As Integer
Dim Lim As Integer
PrimeStatus = True
Lim = Sqr(TestVal)
For I = 2 To Lim
If TestVal Mod I = 0 Then
PrimeStatus = False
Exit For
End If
If I Mod 200 = 0 Then DoEvents
Next I
End Function
该代码中每重复 200 次就调⽤⼀次 DoEvents 语句。这样⼀来,当该环境的其余部分对事件作出响应时,只要有必要,PrimeStatus 过程就可继续计算。
考虑在调⽤ DoEvents 期间发⽣的事情。在其它窗体和应⽤程序处理事件时将暂停执⾏应⽤程序代码。这些事件之⼀有可能是⼀个按钮单击操作,它将再次启动 PrimeStatus 过程。
这将导致重新进⼊ PrimeStatus 过程的,但是,因为在函数每次出现时,堆栈都为其参数和局部变量分配了空间,所以重⼊不会引发冲突。当然,如果过多调⽤ PrimeStatus,则可能出现“溢出堆栈空间”错误。
如果 PrimeStatus 使⽤或改变模块级变量或全局数据,情况就会完全不同。此时,在 DoEvents 能够返回之前执⾏ PrimeStatus 的另⼀个实例,这将导致模块数据或全局数据的值完全不同于它们在调⽤ DoEvents 之前的值。于是,PrimeStatus 的结果将会难以预料。
VB中DoEvents的注意事项
对与再⼤循环⾥ 加⼊ DoEvents却是可以使应⽤程序响应其他程序,但是 DoEvents也会很⼤程度上影响循环的速度,所以⼀般情况我这样⽤
If GetInputState Then DoEvents
虽然多了个判断语句,但速度上确快了很多
⽐较以下代码代码就知道了速度的差别
Private Declare Function GetInputState Lib "user32" () As Long Private Declare Function GetTickCount Lib "kernel32" () As Long Private Sub Command1_Click()
Dim s As Long
s = GetTickCount
For i = 1 To 1000000
DoEvents
Next
MsgBox GetTickCount - s
End Sub
Private Sub Command2_Click()
Dim s As Long
s = GetTickCount
For i = 1 To 1000000
If GetInputState Then DoEvents
Next
MsgBox GetTickCount - s
End Sub
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论