I have a CStatic which displays a plot - X, Y axes, tickmarks, etc. I
want to change scaling of the plot by entering new ranges of X and Y. I
call an overriden OnPaint for that:

CPlot::OnPaint() {
this->Invalidate()
CPaintDC dc(this);
... draw lines and labeles
DeleteDC(dc);
}

The problem is that it gets redrawn on top of the prevous drawing, w/o
first erasing the prevous drawing. I also tried InvalidateRec() w/o
success.

I guess I can fill the whole area with a background color, but this
seems lame. A search of this group showed that Invalidate should work,
but it doesn't! What's the solution then?

BTW... is there a quota of how many questions per day one can ask here?
:) I wonder if I am abusing this group.

Re: redrawing in control with Invalidate() by Victor

Victor
Wed Feb 23 15:57:08 CST 2005

revyakin@yahoo.com wrote:
> [...]
> I guess I can fill the whole area with a background color, but this
> seems lame. A search of this group showed that Invalidate should work,
> but it doesn't! What's the solution then?

IIRC, the solution is to actually make your parent dialog to invalidate
the area of the control for you. And, yes, make sure you tell the dialog
to fill it with the background brush (an optional "erase it" flag). IIRC.

> BTW... is there a quota of how many questions per day one can ask here?
> :) I wonder if I am abusing this group.

If you have to ask, you probably are :-)

Re: redrawing in control with Invalidate() by revyakin

revyakin
Wed Feb 23 16:04:55 CST 2005

Victor, do you mean, I can't this->Invalidate(true), but I have to
pParent->m_plot.Invalidate(true)?


Re: redrawing in control with Invalidate() by Scott

Scott
Wed Feb 23 16:03:08 CST 2005

revyakin@yahoo.com wrote:
> I have a CStatic which displays a plot - X, Y axes, tickmarks, etc. I
> want to change scaling of the plot by entering new ranges of X and Y. I
> call an overriden OnPaint for that:
>
> CPlot::OnPaint() {
> this->Invalidate()
> CPaintDC dc(this);
> ... draw lines and labeles
> DeleteDC(dc);
> }
>
> The problem is that it gets redrawn on top of the prevous drawing, w/o
> first erasing the prevous drawing. I also tried InvalidateRec() w/o
> success.
>
> I guess I can fill the whole area with a background color, but this
> seems lame. A search of this group showed that Invalidate should work,
> but it doesn't! What's the solution then?
>
> BTW... is there a quota of how many questions per day one can ask here?
> :) I wonder if I am abusing this group.
>

Never call OnPaint. For simplicity, let's say that it has hidden
parameters that only the operating system knows.

Call something else that saves any new variables and calls Invalidate().

--
Scott McPhillips [VC++ MVP]


Re: redrawing in control with Invalidate() by Victor

Victor
Wed Feb 23 16:10:39 CST 2005

revyakin@yahoo.com wrote:
> Victor, do you mean, I can't this->Invalidate(true), but I have to
> pParent->m_plot.Invalidate(true)?
>

No, I think you need to figure the rect in the parent that your
control occupies and then tell the parent to InvalidateRect.

I am not that familiar with MFC, sorry.

V

Re: redrawing in control with Invalidate() by revyakin

revyakin
Wed Feb 23 16:14:35 CST 2005

I don't call OnPaint anymore, I made a function redraw() which gets
called either by OnPaint(), or by my "Update Settings" button. Still
does not work.


Re: redrawing in control with Invalidate() by revyakin

revyakin
Wed Feb 23 16:34:20 CST 2005

Well, I did this

CRect parent_rect (0,0,900,500);
m_pParent->InvalidateRect(parent_rect,true);

followed by

CPaintDC dc(this);
///drawing

This erases the old drawing, but prevents the new one from being
drawn... confusing!


Re: redrawing in control with Invalidate() by revyakin

revyakin
Wed Feb 23 17:01:25 CST 2005

well, it did not work anyway


Re: redrawing in control with Invalidate() by Victor

Victor
Wed Feb 23 17:29:16 CST 2005

revyakin@yahoo.com wrote:
> well, it did not work anyway
>

Sorry to hear that.

I have an application and a control in a dialog box, a static, that needs
to be redrawn when some values change (from other controls). I do
'InvalidateRect' for that control and it works like a charm. Try to look
at it again. Maybe you're just missing something simple... Like that
you shouldn't "Invalidate" while responding to WM_PAINT?

Try invalidating it where the information that controls the appearance of
your CPlot actually changes. Use 'm_plot.InvalidateRect'.

V

Re: redrawing in control with Invalidate() by revyakin

revyakin
Wed Feb 23 21:44:06 CST 2005

don't know... tried all possible combinations, no success.


Re: redrawing in control with Invalidate() by Mark

Mark
Wed Feb 23 23:05:49 CST 2005

revyakin@yahoo.com wrote:
> I have a CStatic which displays a plot - X, Y axes, tickmarks, etc. I
> want to change scaling of the plot by entering new ranges of X and Y. I
> call an overriden OnPaint for that:
>
> CPlot::OnPaint() {
> this->Invalidate()
> CPaintDC dc(this);
> ... draw lines and labeles
> DeleteDC(dc);
> }
>
> The problem is that it gets redrawn on top of the prevous drawing, w/o
> first erasing the prevous drawing. I also tried InvalidateRec() w/o
> success.
You are somewhat confused here. Invalidating a region of your window
directs Windows to send a WM_PAINT message to the window to cause the
invalidated area to be redrawn. Invalidating a region within the
WM_PAINT message will cause a WM_PAINT message to be sent... not very
helpful. So don't do that.

Secondly, CPaintDC wraps a BeginPaint/EndPaint call. You should not
delete the DC returned by BeginPaint -- EndPaint does this for you. As
CPaintDC wraps both BeginPaint and EndPaint calls (in the c'tor and
d'tor respectively), then you should call neither function -- just
construct the paint DC.

Finally, as to your desired problem -- your window class does not have a
background brush set. If you do have one set, BeginPaint will erase the
contents of the invalidated area using the background brush. If not,
you are responsible for performing this action, if desired consider:

- the case of blatting a (cached) bitmap to the screen -- there you
don't need to erase the background).
- the case where your background colour is user selectable on a per
object basis. There, you want to erase the background yourself to the
correct colour, which will depend on per window and not per class state.

It isn't lame to erase the background yourself under the second
circumstance. In fact, it's not likely to be much more efficient to
have BeginPaint do it for you -- under the covers, this will likely just
call FillRect or similar anyway.

Finally note that the PAINTSTRUCT has an fErase flag which tells you if
you are responsible for erasing the background, and an rcPaint with the
afflicted region, if you want to know what to erase and whether to erase it.

Re: redrawing in control with Invalidate() by revyakin

revyakin
Thu Feb 24 00:16:25 CST 2005

Mark, thank you, I'll try to set the bg brush.