evolution; the API approach
If there was such a function to
inspect the message queue for user input, we would have a main benefit:
We would speed up our loops ‘cause we would process all the messages in
the queue (with DoEvents) only on user input. It’s faster to check for
a message than to process all messages every time.
API provides us with such a
GetInputState and you can locate it in user32 library.
Here is the declaration:
Public Declare Function GetInputState Lib
"user32" () As Long
The GetInputState function
determines whether there are mouse-button or keyboard messages in the calling
thread's message queue.
If the queue contains one or more new mouse-button or
keyboard messages, the return value is nonzero else if there are no new
mouse-button or keyboard messages in the queue, the return value is zero.
So we can create an improved DoEvents with a Subroutine
like this :
Public Sub newDoEvents()
If GetInputState() <> 0 then DoEvents
can use GetInputState() with many variations for example :
uCancelMode = False
Do until rs.Eof
(..your source here)
If GetInputState() <> 0 then
If uCancelMode Then Exit Do
we could use it in a ScreenSaver e.t.c.
go a little further now and see what exactly is behind GetInputState().
is another API function located in User32 as well; GetQueueStatus()
The GetQueueStatus function indicates the type of messages
found in the calling thread's message queue. Here are the flags that
GetQueueStatus uses :
input, WM_TIMER, WM_PAINT, WM_HOTKEY, or posted message is in the queue.
message is in the queue.
A posted message (other than those listed here) is in the queue.
WM_HOTKEY message is in the queue.
An input message is in the queue.
A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN
message is in the queue.
A WM_MOUSEMOVE message or mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN,
and so on).
A mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
A WM_MOUSEMOVE message is in the queue.
A WM_PAINT message is in the queue.
A posted message (other than those listed here)
is in the queue.
A message sent by another thread or application
is in the queue.
A WM_TIMER message is in the queue.
(I believe that GetInputState() is a GetQueueStatus(QS_HOTKEY Or QS_KEY Or
With these constants you can create your own
GetInputState function that fits your needs. For example you can create a custom
function that issues DoEvents when it’ll detects not only a Keyboard or Mouse
Key input, but also a WM_PAINT signal.
Why’s that? ‘cause in your loop you might need
to update the screen so you must let your custom function process the specific
Look at this :
Public Const QS_HOTKEY = &H80
Public Const QS_KEY = &H1
Public Const QS_MOUSEBUTTON = &H4
Public Const QS_MOUSEMOVE = &H2
Public Const QS_PAINT = &H20
Public Const QS_POSTMESSAGE = &H8
Public Const QS_SENDMESSAGE = &H40
Public Const QS_TIMER = &H10
Public Const QS_ALLINPUT = (QS_SENDMESSAGE
Or QS_PAINT Or QS_TIMER Or
QS_MOUSEBUTTON Or QS_MOUSEMOVE Or QS_HOTKEY Or
Public Const QS_MOUSE = (QS_MOUSEMOVE
Public Const QS_INPUT = (QS_MOUSE Or
Public Const QS_ALLEVENTS = (QS_INPUT
Or QS_POSTMESSAGE Or QS_TIMER Or
QS_PAINT Or QS_HOTKEY)
Public Declare Function GetQueueStatus
Lib "user32" (ByVal qsFlags As Long) As Long
Public Function cGetInputState()
qsRet As Long
qsRet = GetQueueStatus(QS_HOTKEY Or
QS_KEY Or QS_MOUSEBUTTON Or QS_PAINT)
cGetInputState = qsRet
With this function you can trigger the DoEvents to
be executed only when the message queue contains Key input, Mouse button or a
Call it like this….
. . if cGetInputState() <> 0
tested and proved to optimise a loop by
I wrote this article believing that the API is a
powerfull part on Windows programming and deserves your attention. I was stuck
several times and API prooved to be a problem solver. API is a large world but
with little effort, you can take advantage of it. You will create more
sophisticated and user aware programs.
I hope I helped.
Any comments or suggestions are always welcomed.
(Below there is a link to the .doc version of this article, for you to download.
If you want to implement this source in your projects, download the Class Module posted by http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=1&txtCodeId=33401 John Baughman in this address
Also, you can check out Olav Jordan's article : http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=37888&lngWId=1 Optimized loop (no more doevents)
Need Oracle tips? try here : http://aboutoracle.blogspot.com