Re: timer not being called when OnPaint calls Invalidate

Tech-Archive recommends: Speed Up your PC by fixing your registry



"grayaii" <grayaii@xxxxxxxxx> wrote in message
news:1164678497.496520.123790@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[...]
I have my onpaint function call Invalidate at the very end like so:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
// Draw everything...
this.Invalidate()
}

Let me make sure I understand what you are saying:

In your overridden "OnPaint" handler, which is called in response to a paint
event, which occurs any time an area of the control (form) is invalidated,
you invalidate the entire control (form)?

Seems to me you've got a pretty classic infinite loop there.

The problem is that I want to setup a System.Windows.Forms.Timer when I
click the a certain key for instance. When I hit the key, I create a
timer successfully, but the timer's event never gets called after I
start the timer.. It seems the "this.Invalidate" within OnPaint does
not give the form the opportunity to call the tick-event of the timer.

Sure, I can believe that. If you fill your message queue with paint events,
I can see how you might never get to a point where you can pull out the
timer event.

I believe the problem (and ultimately the solution) lies in the fact
that the form is a single-threaded application. In my own ignorance, I
thought that when you create a timer it creates a new thread,
independent of the message loop of the application, but apparently not.

Not using the Forms.Timer method of creating a timer, no. All that does is
use the usual Windows WM_TIMER mechanism, which relies on being able to get
a WM_TIMER message from the window's message queue.

If you want a timer that operates independently of the message queue, you
should probably use something like Threading.Timer instead. That will use a
different thread to handle the timer. Of course, if your timer code has to
interact with the window, you will wind up having to use Invoke or
BeginInvoke, which introduces a dependency on the message queue again.
Otherwise, it should be fine though.

IMHO, however, you should rethink the wisdom of calling Invalidate from
within your OnPaint handler. This is very bad form. Generally speaking,
you should only ever call Invalidate when there has actually been some
change in the data being drawn. It makes no sense to call Invalidate when
what you've just done is to have redrawn the control. Nothing about drawing
the control should be changing the way it should draw next time, and so
there should be no reason to call Invalidate from within the OnPaint
handler.

[...]
I'm soooo close to the solution that I can almost taste it, but I'm
stuck. The words, "Multithreaded app" screams at me.

You may or may not need to introduce a new thread into your program. That
depends on exactly what you're trying to do. However, personally I would
first attempt to solve your problem simply by removing the Invalidate from
the OnPaint handler. If your timer does something that requires the control
(form) to be redrawn, then call Invalidate there (assuming you have to...in
most simple cases, a form contains only controls that already know to
invalidate themselves if their data changes...simply setting the control's
data is enough).

Pete


.



Relevant Pages

  • Re: timer not being called when OnPaint calls Invalidate
    ... My application is actually a game, which is why OnPaint has to be ... Why those events work and not the timer is beyond ... I have my onpaint function call Invalidate at the very end like so: ...
    (microsoft.public.dotnet.languages.csharp)
  • MouseMove
    ... um mittels Invalidate() ein CrossHair in OnPaint des Ocx zu bewegen. ... Der Dialog hat einen Timer, und ruft mit der Frequenz 25ms eine Funktion ...
    (microsoft.public.de.vc)
  • Re: MouseMove
    ... und nur den Fordergrund in OnPaint (ein par tracker und das crosshair) ... Also habe ich nun mit OnPaint auch den Hintergrund neu gemalt. ... Wenn ich nun die Maus andauernd bewege, wird der Timer ... Aktivität und den permanenten Invalidate wird kein WM_PAINT gesendet. ...
    (microsoft.public.de.vc)
  • Re: WM_PAINT and redrawing the active window
    ... will be until the OnPaint handler is called, so any cached value can be invalidated at any ... And while you can create a bitmap and keep it around, assuming that whatever size it is ... invalidate at least the area you expect to see drawn. ... ONLY the OnPaint handler knows how to render the image. ...
    (microsoft.public.vc.mfc)
  • Re: Invalidating a region and having only that region drawn
    ... I will need to rethink my drawing strategy paying closer attention to the ... > The system stores the results of invalidate calls internally. ... > is to run the OnPaint override which in turn kicks of the Paint event. ... >> to the form's update region resulting in only that region being redrawn at ...
    (microsoft.public.dotnet.framework.drawing)