Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Application.DoEvents() resets cursor?

232 views
Skip to first unread message

Michael Covington

unread,
Apr 22, 2009, 9:00:45 PM4/22/09
to
Why does Application.DoEvents() reset the cursor (Cursor.Current) to
Cursors.Default from Cursors.WaitCursor? Is this intentional or a
long-standing WinForms bug?

Peter Duniho

unread,
Apr 23, 2009, 12:27:06 AM4/23/09
to

I suspect that what you're seeing is the normal behavior when the events
are pumped and you haven't set the cursor properly in the first place.
I'll bet that even if you fix your code so that it's not using
Application.DoEvents(), but instead is simply not blocking the main GUI
thread in the first place, you'd still see your cursor get reset on the
next event.

Instead of setting Cursor.Current, set the Cursor for the control/form
where the specific cursor is relevant. Oh, and fix your code so you don't
have to use DoEvents(). :p

Pete

Michael Covington

unread,
Apr 23, 2009, 12:37:09 AM4/23/09
to
Peter Duniho wrote:
>> Why does Application.DoEvents() reset the cursor (Cursor.Current) to
>> Cursors.Default from Cursors.WaitCursor? Is this intentional or a
>> long-standing WinForms bug?
>
> I suspect that what you're seeing is the normal behavior when the events
> are pumped and you haven't set the cursor properly in the first place.
> I'll bet that even if you fix your code so that it's not using
> Application.DoEvents(), but instead is simply not blocking the main GUI
> thread in the first place, you'd still see your cursor get reset on the
> next event.
>
> Instead of setting Cursor.Current, set the Cursor for the control/form
> where the specific cursor is relevant. Oh, and fix your code so you
> don't have to use DoEvents(). :p

Hmmm... Does this mean Cursor.Current is useless? Then why did they
give it to us?

duna...@gmail.com

unread,
Apr 23, 2009, 9:31:07 AM4/23/09
to
On Apr 22, 8:00 pm, Michael Covington

From the docs:

<quote>
If you call Application..::.DoEvents before resetting the Current
property back to the Cursors..::.Default cursor, the application will
resume listening for mouse events and will resume displaying the
appropriate Cursor for each control in the application.
</quote>

Michael Covington

unread,
Apr 23, 2009, 9:52:18 AM4/23/09
to

Well, they say it works the way it does -- but why did they make it that
way? What use is Cursor.Current if it's liable to being reset
asynchronously?

Ignacio Machin ( .NET/ C# MVP )

unread,
Apr 23, 2009, 2:59:20 PM4/23/09
to
On Apr 22, 9:00 pm, Michael Covington

Why you need to call DoEvents() in the first place?

IMHO DoEvents should be avoided at all cost.

Tom Dacon

unread,
Apr 23, 2009, 10:48:45 PM4/23/09
to
Two people in this thread have asked why you would ever need to call
Application.DoEvents. I know of no reason where it's necessary, but there's
one place where it's useful: In a Windows Forms application, when control
returns to your code after a call to MessageBox.Show, calling DoEvents
immediately before beginning a time-consuming operation that doesn't let
events get handled allows the rectangle under the MessageBox dialog to be
repainted. In VB6, there were occasions where DoEvents was useful for other
things, but in VB.Net this is the only place where I find it useful.

Tom Dacon
Dacon Software Consulting

"Michael Covington" <for.addr...@www.ai.uga.edu.slash.mc> wrote in
message news:uxGDu76w...@TK2MSFTNGP04.phx.gbl...

Peter Duniho

unread,
Apr 23, 2009, 11:01:43 PM4/23/09
to
On Thu, 23 Apr 2009 19:48:45 -0700, Tom Dacon <tda...@community.nospam>
wrote:

> Two people in this thread have asked why you would ever need to call
> Application.DoEvents.

Minor nit: only one person asked that question, and I'll bet if you ask
him about it, you'll find it was rhetorical.

> I know of no reason where it's necessary, but there's one place where
> it's useful: In a Windows Forms application, when control returns to
> your code after a call to MessageBox.Show, calling DoEvents immediately
> before beginning a time-consuming operation that doesn't let events get
> handled allows the rectangle under the MessageBox dialog to be
> repainted. In VB6, there were occasions where DoEvents was useful for
> other things, but in VB.Net this is the only place where I find it
> useful.

Um. The point is that when you assume "before beginning a time-consuming
operation that doesn't let events get handled", there's already proof of a
problem.

In the scenario you describe, you can actually address the redraw issue as
easily simply by calling the Update() method of the form. But neither
approach addresses the actual problem that you are getting ready to block
event handling again. So, great...you've redrawn the form after the
MessageBox, but what happens when the user switches to some other
application that obscures your form, and then comes back? Same redraw
problem.

If you accept "a time-consuming operation that doesn't let events get
handled" as proper design (which I don't, by the way), _and_ you're going
to use Application.DoEvents() rather than block the UI entirely, then do
it right: call Application.DoEvents() periodically during your
time-consuming operation, not just right when you start it.

But even better, use a different thread to run the time-consuming
operation, and avoid the whole "doesn't let events get handled" part
altogether.

Pete

not_a_commie

unread,
Apr 24, 2009, 10:31:50 AM4/24/09
to

Tom Dacon

unread,
Apr 25, 2009, 11:49:31 AM4/25/09
to
> If you accept "a time-consuming operation that doesn't let events get
> handled" as proper design (which I don't, by the way), _and_ you're going
> to use Application.DoEvents() rather than block the UI entirely, then do
> it right: call Application.DoEvents() periodically during your
> time-consuming operation, not just right when you start it.

You're "teaching your grandmother to suck eggs", here, Duniho. Why is it
that everyone on these groups seems to automatically assume when they
respond to a post that they're talking to an incompetent? Is it just the
chronic passive-aggressive attitude that seems endemic to newsgroups?

By "time-consuming operations" I'm talking about sub-second operations for
which the lack of underpainting is mererly an annoying visual glitch. It's a
UI refinement, nothing more, to contribute to the professional appearance of
the apps. For real "time-consuming operations" I'd customarily put them on a
worker thread or throw in a DoEvents at sufficiently-short intervals to keep
the app's UI responsive.

Jeez.

Peter Duniho

unread,
Apr 25, 2009, 12:49:11 PM4/25/09
to
On Sat, 25 Apr 2009 08:49:31 -0700, Tom Dacon <tda...@community.nospam>
wrote:

>> If you accept "a time-consuming operation that doesn't let events get

>> handled" as proper design (which I don't, by the way), _and_ you're
>> going to use Application.DoEvents() rather than block the UI entirely,
>> then do it right: call Application.DoEvents() periodically during your
>> time-consuming operation, not just right when you start it.
>
> You're "teaching your grandmother to suck eggs", here, Duniho. Why is it
> that everyone on these groups seems to automatically assume when they
> respond to a post that they're talking to an incompetent?

Because people write posts that make them appear to be an incompetent.

> Is it just the chronic passive-aggressive attitude that seems endemic to
> newsgroups?

See above.

> By "time-consuming operations" I'm talking about sub-second operations
> for which the lack of underpainting is mererly an annoying visual glitch.

Then why call DoEvents()? A call to Update() would be sufficient, if
you've just got the one form you're dealing with.

In any case, if the operation is long enough to justify something like
that, it's long enough to justify putting into a thread. The fact is that
in many cases, the OS has already saved the underlying contents of an
overlapped window and can restore it without any such finagling. But if
you've got an operation that might be slow enough for the user to notice
and be annoyed by it, then you've got an operation that should be moved
into a thread.

You have no way to ensure that what's a "sub-second operation" on your own
computer is always a "sub-second operation" on the user's computer. So by
inserting a little UI hack like this, you create an illusion of correct
behavior, without actually having correct behavior. And for those users
where the operation is delayed longer than you expected, your hack winds
up exposed.

> It's a UI refinement, nothing more, to contribute to the professional
> appearance of the apps.

I guess that's in the eye of the beholder. My own personal feeling is
that fooling the user into thinking you've written the code correctly is
not nearly as professional an approach as _actually_ writing the code
correctly.

> For real "time-consuming operations" I'd customarily put them on a
> worker thread or throw in a DoEvents at sufficiently-short intervals to
> keep the app's UI responsive.

Well, as I already pointed out, I don't consider the latter strategy
appropriate anyway.

> Jeez.

Jeez, indeed.

Pete

Tom Dacon

unread,
Apr 25, 2009, 3:50:29 PM4/25/09
to

"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote in message
news:op.usybn...@macbook-pro.local...

> On Sat, 25 Apr 2009 08:49:31 -0700, Tom Dacon <tda...@community.nospam>
> wrote:

> Because people write posts that make them appear to be an incompetent.

> See above.

I guess you missed my point. In a person-to-person discussion, most people
in our line of work exercise a certain amount of respectful collegiality.
It's part of behaving like a mature adult. On the programming newsgroups
just about everything, including your comments to my post, turns into a
pissing contest. I say to hell with it. A pox on all your houses.

On the other hand, your suggestion of using Update is a good one. I'll adopt
it in the future. I'll be the judge of whether the operations that follow my
messagebox calls deserve a thead. I doubt that even you put every simple
database query into its own thread, and I further doubt that I'll start
doing so just because of your complaints.

Thanks for your comments.

Peter Duniho

unread,
Apr 25, 2009, 4:49:37 PM4/25/09
to
On Sat, 25 Apr 2009 12:50:29 -0700, Tom Dacon <tda...@community.nospam>
wrote:

>
> "Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote in message
> news:op.usybn...@macbook-pro.local...
>> On Sat, 25 Apr 2009 08:49:31 -0700, Tom Dacon <tda...@community.nospam>
>> wrote:
>
>> Because people write posts that make them appear to be an incompetent.
>> See above.
>
> I guess you missed my point.

And I guess you missed mine.

> In a person-to-person discussion, most people in our line of work
> exercise a certain amount of respectful collegiality.

It's true, in a person-to-person discussion, a person who makes a blanket,
unqualified statement about a particular programming technique would be
offered more quickly an opportunity to explain themselves.

But it certainly hasn't been my experience that such statements go
completely uncontested, just because it's a person-to-person discussion.

Likewise, if you post such a blanket, unqualified statement about a
particular programming technique, you have to be willing to accept that it
may be contested. Instead of having a temper tantrum, you might consider
simply taking that opportunity to explain yourself, just as one hopes you
might in a person-to-person discussion.

And for the record, I would be telling you in as many words to let go of
techniques that use DoEvents(), Refresh(), or Update(), even in a
person-to-person discussion. How do I know this? Because I've had this
very discussion with other people person-to-person, and there has been no
difference in statements between this discussion and those.

A true "mature adult" can tolerate disagreement without feeling
persecuted, insulted, or threatened. I admit, most chronologically mature
adults turn out to not be nearly as emotionally mature as one would hope
them to be. But that's an explanation, not an excuse.

> It's part of behaving like a mature adult. On the programming newsgroups
> just about everything, including your comments to my post, turns into a
> pissing contest. I say to hell with it. A pox on all your houses.

My statements have all been factual, technically relevant. Yours have
been increasingly personal in nature.

I'm not convinced you have proven yourself qualified to make
pronouncements about what is and what is not "part of behaving like a
mature adult".

Pete

Michael Covington

unread,
Apr 25, 2009, 9:23:29 PM4/25/09
to
> On the other hand, your suggestion of using Update is a good one...

Could the experts expound on the exact difference between DoEvents and
Update? Why, exactly, is DoEvents provided to us?

Peter Duniho

unread,
Apr 25, 2009, 9:44:26 PM4/25/09
to

DoEvents() dequeues and dispatches every window message in the thread's
message queue, until the queue is empty. Update() doesn't do anything
with messages; it simply invokes the appropriate window paint handler for
the target Control instance. Oddly enough, this is basically the
description found on MSDN; was there something about the docs that is
confusing you?

I can't explain exactly why they even exist. If I had my way, they
wouldn't. :p

I suspect that they are to some extent a legacy from the aspects of the VB
API that .NET inherited. As far as I can recall, there's no equivalent
Win32 function. But if you want to know for sure, you'd have to ask the
Microsoft folks that put it in there in the first place why they are there.

Pete

Scott Seligman

unread,
Apr 25, 2009, 10:30:02 PM4/25/09
to
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:
>message queue, until the queue is empty. Update() doesn't do anything
>with messages; it simply invokes the appropriate window paint handler
>for the target Control instance.

Update() absolutely uses window messages to do the work. This is easily
verifiable, though I suppose it's an implementation detail, as the
documentation doesn't mention it.

>I suspect that they are to some extent a legacy from the aspects of
>the VB API that .NET inherited. As far as I can recall, there's no
>equivalent Win32 function.

Application.DoEvents() == PeekMessage(), TranslateMessage(),
DispatchMessage() (and potentially others for some message pumps)

Control.Update() == UpdateWindow()
Indeed, UpdateWindow() is the API .NET uses when you call .Update()

--
--------- Scott Seligman <scott at <firstname> and michelle dot net> ---------
The most painful state of being is remembering the future, especially
one which you know will never come.
-- Soren Kierkegaard

Peter Duniho

unread,
Apr 26, 2009, 12:24:26 AM4/26/09
to
On Sat, 25 Apr 2009 19:30:02 -0700, Scott Seligman <seli...@example.com>
wrote:

> "Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:
>> message queue, until the queue is empty. Update() doesn't do anything
>> with messages; it simply invokes the appropriate window paint handler
>> for the target Control instance.
>
> Update() absolutely uses window messages to do the work. This is easily
> verifiable, though I suppose it's an implementation detail, as the
> documentation doesn't mention it.

It does and it doesn't. It invokes the paint handler via WM_PAINT. But,
unlike using DoEvents(), it's not relying on the usual invalidate/dequeue
message mechanism. It's invoking the handler directly, not posting a
message in the message queue and waiting for the message to be dequeued
and dispatched.

>> I suspect that they are to some extent a legacy from the aspects of
>> the VB API that .NET inherited. As far as I can recall, there's no
>> equivalent Win32 function.
>
> Application.DoEvents() == PeekMessage(), TranslateMessage(),
> DispatchMessage() (and potentially others for some message pumps)

Obviously within DoEvents(), there is a working windows message pump.
Obviously, you can code a message pump using the Win32 functions.

That doesn't mean that Win32 includes a function like DoEvents().

> Control.Update() == UpdateWindow()
> Indeed, UpdateWindow() is the API .NET uses when you call .Update()

Right...I should have been more clear. The reason I wrote "no equivalent
Win32 function [singular]" is that I was specifically talking about
DoEvents(), not all of the methods in .NET being discussed here.

Pete

Ben Voigt [C++ MVP]

unread,
Apr 29, 2009, 10:09:34 AM4/29/09
to
Scott Seligman wrote:
> "Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:
>> message queue, until the queue is empty. Update() doesn't do anything
>> with messages; it simply invokes the appropriate window paint handler
>> for the target Control instance.
>
> Update() absolutely uses window messages to do the work. This is
> easily verifiable, though I suppose it's an implementation detail, as
> the documentation doesn't mention it.

Yes but SendMessage bypasses the queue. The correct statement would have
been "Update() doesn't involve the message queue".


0 new messages