How DoEvents Works: The Nitty-Gritty Technical Details
A peek behind the scenes at the inner workings of the DoEvents function.
This is part 5 of a multi-part series on the DoEvents function.
I have a confession to make. I wrote an entire five-part series of blog posts just so I had an excuse to quote the two paragraphs below.
Several weeks ago, I tumbled down some esoteric VBA/VB6 rabbit hole on the interwebs. As I struggled to make sense of a concept soaring over my head, a comment caught my eye. In explaining this complex topic, the comment poster referenced the book Advanced Visual Basic 6, by Matthew Curland.
As I've come to learn, finding insights into deep topics in VBA is surprisingly difficult (it's part of the reason I started this blog). Since VBA and VB6 are essentially the same language (as opposed to VB6 and VB.NET, which are very different languages that just happen to share a name and a great deal of syntax), I've found that the best way to get information on advanced VBA topics is to buy decades-old books about VB6.
From page 308 of Advanced Visual Basic 6:
Visual Basic provides the DoEvents function for arbitrarily clearing pending messages in all the current thread's windows. Since pending methods masquerade as messages, calling DoEvents lets them through. The problem is that DoEvents lets everything else through as well. You get a flood instead of a trickle. If you want only the trickle, you'll have to use something other than DoEvents.
DoEvents first clears all pending keystrokes from the SendKeys function and then enters a loop that clears all messages with the PeekMessage API. Finally, DoEvents calls the Sleep API to release the remaining time slice on the current thread.
Here's a summary of the text in bullet-point form:
- Clear all pending keystrokes from the SendKeys function
- Clear all window messages with the PeekMessage API
- Call the Sleep API (probably with an argument of 0)