[Top-posting undone for clarity.]
>>> I have an application which is heavily graphics intensive, all the graphics being custom.
>>>
[quoted text clipped - 3 lines]
>>
>> You are breaking rule 1 of Windows painting. Don't do that.
[responding to Scott]
I would not go quite that far. For most applications, that is
a reasonable guideline, but not all and I believe Mr. Rounds
has one that does not quite fit the norm. More below.
>> Do
>> MyView->Invalidate();
[quoted text clipped - 3 lines]
>> The OnPaint/OnDraw functions use BeginPaint/EndPaint APIs, which are only valid when processing a Windows-generated WM_PAINT
>> message.
It would be more correct to say that the caller
of OnDraw() utilizes the {Begin,End}Paint APIs.
I believe the contract for OnDraw() is that it will
draw given a display context, as Mr. Rounds has
supposed.
> The reason OnDraw() gets called throughout this app is that the app controls an external piece of lab equipment ( actually 3 ),
> and collects & presents data from one of the machines. Each of the machines, and of course the user, can instigate a need to
> redraw one of the views, with one machine instigating a need to redraw the view every second. The OnDraw() function switches on
> some data in the associated Doc to determine if the entire view needs to be redrawn, or simply has to add the next line segment(s)
> in the graph. What I was trying to do in all of this was to minimize the amount of work involved in each update to the view.
Despite my comments about the OnDraw() contract,
I believe you would be better off to decompose the
drawing work into at least two parts: (1) the part
needed to refresh the display when windows are
shown or uncovered; and (2) the part that causes
recent incremental update of the displayed data.
Then, OnDraw() can call upon (or be) part 1 and
whatever knows about new updates can call upon
part 2, passing in its special knowledge of what the
minimal update might be. Part 2 may also need to
be abortable or deferable under circumstances where
updates come in too rapidly and your app does not
get the priority needed to keep up.
> So, the real reason I am responding except to say thanks is that it is entirely possible that I have taken the wrong approach to
> this and I wanted to understand your response better. I really can't just repaint the entire for each new data point, that would
> be too graphics intensive. With this further input, do you still think I have taken the wrong approach?
Your presenting problem is readily cured by simply
being more careful with DC acquisition and disposal.
There is no reason that you cannot simply get the DC,
clear some minimal background, draw what is new or
cleared, and relinquish the DC. The GDI is very good
about detecting and discarding draws that will not show
up at all and clipping draws that will partially appear.
Just don't hack up OnDraw() to optimize the distinction
between ordinary refresh and incremental update.
By the way, I have solved this same problem for
a continuously updating sonar display.
> Any further input would be appreciated.
Please refrain from top-posting. There are many
good reasons that people learn to avoid it.
> Phil

Signature
--Larry Brasfield
email: donotspam_larry_brasfield@hotmail.com
Above views may belong only to me.
> The reason OnDraw() gets called throughout this app is that the app
> controls an external piece of lab equipment ( actually 3 ), and collects &
[quoted text clipped - 11 lines]
> for each new data point, that would be too graphics intensive. With this
> further input, do you still think I have taken the wrong approach?
You are still breaking Rule 1 of Windows painting.
Have you experimented with covering and then uncovering parts of your
view with some other program's window? What happens, for example, if
you bring up the Windows clock and move that window around? According
to your description, your view would not properly repaint when uncovered.
In other words, your doc variables do not know enough to determine how
much of the view needs to be redrawn.
The solution is to call the view Invalidate() to force the whole view to
repaint, or you can call InvalidateRect() if you want to request only a
partial repaint. To reduce or avoid unnecessary repainting the OnDraw
code can call GetClipBox to determine how much of the view to redraw.
GetClipBox gives you the union of the area you invalidated and the area
that Windows may have invalidated.

Signature
Scott McPhillips [VC++ MVP]