DoEvents and Application Performance

June 22 2010

DoEvents has long been held as the "Fix all" for any problems a VB programmer has. Time and again I've heard developers say "Just throw a DoEvents in there and that'll fix it", without understanding what DoEvents actually does.

Calling DoEvents hands control of the CPU over to the operation system. The operating system then retrieves and processes all messages in the Windows Message Queue (like paint, resize, etc). This is why when calling DoEvents inside a long running process (large loop for example), the application UI doesn't become a white screen, and you can move the form around.

The thing is, DoEvents processes all messages currently in the message queue, and thus your application will process more slowly.

A better solution is to use the PeekMessage, TranslateMessage, and DispatchMessage API calls that interact with the message queue. Using these message you can retrieve one message from the queue at a time and thus your application will complete its task faster. (Remaining message queue messages can be processed when your application work has completed and the user is looking at the UI, thinking about what to do next).

To directly simulate DoEvents you can use the following construct (when called from forms. If not called from a form, pass 0 into the second argument):

Private Type PointAPI
X As Long
Y As Long
End Type

Public Type msg
hwnd As Long
Message As Long
wParam As Long
lParam As Long
time As Long
pt As PointAPI
End Type

Dim lpMsg as msg

Do While PeekMessage(lpMsg, Me.hWmd, 0, 0, PM_REMOVE)
TranslateMessage lpMsg
DispatchMessage lpMsg

When calling DoEvents in loops, replace DoEvents with the following construct:

Dim lpMsg as msg

If PeekMessage(lpMsg, 0, 0, 0, PM_REMOVE) Then
TranslateMessage lpMsg
DispatchMessage lpMsg
End If

Details of these three win32 api calls can be found here:

PeekMessage -
TranslateMessage -
DispatchMessage -

Post a comment

comments powered by Disqus