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
Public Type msg
hwnd As Long
Message As Long
wParam As Long
lParam As Long
time As Long
pt As PointAPI
Dim lpMsg as msg
Do While PeekMessage(lpMsg, Me.hWmd, 0, 0, PM_REMOVE)
When calling DoEvents in loops, replace DoEvents with the following construct:
Dim lpMsg as msg
If PeekMessage(lpMsg, 0, 0, 0, PM_REMOVE) Then
Details of these three win32 api calls can be found here:
PeekMessage - http://msdn2.microsoft.com/en-us/library/ms644943.aspx
TranslateMessage - http://msdn2.microsoft.com/en-us/library/ms644955.aspx
DispatchMessage - http://msdn2.microsoft.com/en-us/library/ms644934.aspx