Drawing continuously(dynamically) in MFC .  
Author Message
datadayandnite





PostPosted: Tue Aug 21 10:44:12 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC .

Hi Folks,


I have to develop an application in which I would like to paint the
screen (view/dialog) as long as the application exists. I am recieving
some data from the below layers and I should paint the screen
accordingly. In betwwn user may click on the screen , can change the
color of the line I have drawn etc.

Correct me If I am wrong..If I draw my screen from OnPaint or OnDraw()
my application would hang and I want to handle other events also so
this option is ruled out.

So what may be the solution , I have to remember what I have drawn
using some data structure and tell Onpaint function to draw those
everytime it gets called ?
or is there any other better way of doing that?

Please post a link to a sample if u have .

Regards,
JustLikeDat

Visual Studio285  
 
 
Jonathan





PostPosted: Tue Aug 21 10:44:12 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . I'm not sure if I understand exactly what you want but you should definitely
avoid a loop in OnDraw() if that is what you are asking.

The first thing I would do is optimize OnDraw() so that it is very efficient
by being able to draw only the data that's changed, and scrolling the window
contents if needed rather than simply redrawing the entire screen. Use the
Hint argument if at all possible.

Second, then call OnUpdate()/OnUpdateAllViews() whenever the data changes.
This could be called whenever you receive new data. Or, if that's not
possible, use a timer handler that calls the update routine.

You definitely need to coorperate with the Windows model of handling events.
An endless loop anywhere in your main thread would definitely be bad. But,
if for some reason the above approach doesn't work for you, you could also
consider creating a worker thread that loops. It would have to constantly
test some variable to see if it should stop that the rest of your program
could set.

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com




> Hi Folks,
>
>
> I have to develop an application in which I would like to paint the
> screen (view/dialog) as long as the application exists. I am recieving
> some data from the below layers and I should paint the screen
> accordingly. In betwwn user may click on the screen , can change the
> color of the line I have drawn etc.
>
> Correct me If I am wrong..If I draw my screen from OnPaint or OnDraw()
> my application would hang and I want to handle other events also so
> this option is ruled out.
>
> So what may be the solution , I have to remember what I have drawn
> using some data structure and tell Onpaint function to draw those
> everytime it gets called ?
> or is there any other better way of doing that?
>
> Please post a link to a sample if u have .
>
> Regards,
> JustLikeDat
>

 
 
AliR





PostPosted: Tue Aug 21 10:48:42 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . If you are going to draw continuously you will block everything no matter
what. I would suggest drawing every so often (Every 500 millseconds or so).
TVs refresh at 30 frames pre second, and a human eye can't really see the
refresh rate at 20 frames per second.
Anyway, if I was doing this I would probably do the drawing to an offscreen
DC/Bitmap and then force a WM_PAINT (Invalidate(),UpdateWindow()) when the
new image is ready. If the drawing takes too long you can even put the
drawing to the offscreen bitmap in a seperate thread.

AliR.




> Hi Folks,
>
>
> I have to develop an application in which I would like to paint the
> screen (view/dialog) as long as the application exists. I am recieving
> some data from the below layers and I should paint the screen
> accordingly. In betwwn user may click on the screen , can change the
> color of the line I have drawn etc.
>
> Correct me If I am wrong..If I draw my screen from OnPaint or OnDraw()
> my application would hang and I want to handle other events also so
> this option is ruled out.
>
> So what may be the solution , I have to remember what I have drawn
> using some data structure and tell Onpaint function to draw those
> everytime it gets called ?
> or is there any other better way of doing that?
>
> Please post a link to a sample if u have .
>
> Regards,
> JustLikeDat
>


 
 
Doug





PostPosted: Tue Aug 21 10:53:19 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC .

>Hi Folks,
>
>
>I have to develop an application in which I would like to paint the
>screen (view/dialog) as long as the application exists. I am recieving
>some data from the below layers and I should paint the screen
>accordingly. In betwwn user may click on the screen , can change the
>color of the line I have drawn etc.
>
>Correct me If I am wrong..If I draw my screen from OnPaint or OnDraw()
>my application would hang

Why do you say that?

>and I want to handle other events also so
>this option is ruled out.

You would never enter a loop to repaint the screen over and over again. If
you wanted to do animation, you would use some timer-based method that
returns to the message loop regularly.

>So what may be the solution , I have to remember what I have drawn
>using some data structure and tell Onpaint function to draw those
>everytime it gets called ?

In a nutshell, that's it. You have to be able to paint the invalid part of
your window whenever you receive the WM_PAINT message. I'm sure MSDN has a
lot more on this.

>or is there any other better way of doing that?
>
>Please post a link to a sample if u have .

See the Scribble and DrawCLI examples.

--
Doug Harrison
Visual C++ MVP
 
 
David





PostPosted: Tue Aug 21 13:26:25 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC .



> I have to develop an application in which I would like to paint the
> screen (view/dialog) as long as the application exists. I am recieving
> some data from the below layers and I should paint the screen
> accordingly. In betwwn user may click on the screen , can change the
> color of the line I have drawn etc....

All Windows applications should paint the client area of window in response
to WM_PAINT messages. You make sure you get a WM_PAINT message by using
Invalidate() or InvalidateRect() to tell Windows that an area needs
painting.

In the MFC doc-view architecture, you store data in the document which
determines the visible appearance, and paint the view window according to
its contents.

So when you receive data, (from a user action or from anywhere else) you use
it to update the document, and having done so you invalidate the appropriate
area of the view(s). You'll then get a WM_PAINT message whch tells you
which area to draw.

The important thing is that Windows is quite clever about sending WM_PAINT
messages. If two or three things happen at once, the idea is that you won't
be waiting fo the window to be updatae only to have it updated again.

So "continuous drawing" is just a question of "regular invalidation", and
allowing the drawing to happen when Windows wants you to do it.

[There's also UpdateWindow() which forces redrawing of all invalid areas
"now" - but you may be able to get by without it.]

Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mzusers/mailinglist.htm







 
 
Joseph





PostPosted: Tue Aug 21 15:09:50 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . I don't see why drawing your screen from OnPaint or OnDraw has the effect you describe.
Why would the application hang? They do their drawing, they return, life goes on.

If you have some source of data, the more common approach is to start one or more threads
that obtain the data, so they do not interfere with what you are doing in the main GUI
thread.

For low data rates you can PostMessage from the thread to the main GUI thread to cause
redrawing to happen. See my essay on worker threads on my MVP Tips site, or my essay on
serial port I/O. For high data rates, see my essay on I/O Completion Ports as an
interthread queueing mechanism.

Note that at any instant, you need to have EVERYTHING necessary to COMPLETELY redraw the
contents of a window at any moment, without warning. So what you would be doing with the
PostMessage is recording whatever is required to redraw the display, but it doesn't
actually redraw it. Instead, it selectively will InvalidateRect whatever part of the
display requires redrawing. I use a technique like this to draw real-time data from a
mass spectrometer which is running continuously. I have one thread to send requests to
the MS, one to receive its replies, another to send the data to a named pipe so the user
can get the raw data stream, and of course the main GUI thread to do the actual drawing.
It is reasonably straightforward to do this, and is the normal way this sort of thing is
handled.
joe



>Hi Folks,
>
>
>I have to develop an application in which I would like to paint the
>screen (view/dialog) as long as the application exists. I am recieving
>some data from the below layers and I should paint the screen
>accordingly. In betwwn user may click on the screen , can change the
>color of the line I have drawn etc.
>
>Correct me If I am wrong..If I draw my screen from OnPaint or OnDraw()
>my application would hang and I want to handle other events also so
>this option is ruled out.
>
>So what may be the solution , I have to remember what I have drawn
>using some data structure and tell Onpaint function to draw those
>everytime it gets called ?
>or is there any other better way of doing that?
>
>Please post a link to a sample if u have .
>
>Regards,
>JustLikeDat
Joseph M. Newcomer [MVP]

Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
 
 
ggurubasavaraja





PostPosted: Wed Aug 22 01:40:53 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . Thanks a lot for ur replies.

I think I undesrstood how to draw continuously onto a screen (window/
view) . But I dont have any idea about how to store what I have
drawn.
Say for example I have drawn 3 bitmaps and 4 lines between those
bitmaps .I should have a data structure which would contain the
position of the itmes I have drawn, the size etc. And I will keep on
addding new items to this pool.
I think I ll have to impliment this mechanism in document also. Then
draw these items everytime in the WM_PAINT handler or my OnDraw()
function.
For a big GDI application I think this would be very critical as the
speed of the application depends on this.
Is there any optimal mechanism to impliment this? if I use GDI+ would
this implimentation change?
Please throw some light on this ..


 
 
Dan





PostPosted: Wed Aug 22 01:45:04 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC .



> Thanks a lot for ur replies.
>
> I think I undesrstood how to draw continuously onto a screen (window/
> view) . But I dont have any idea about how to store what I have
> drawn.
> Say for example I have drawn 3 bitmaps and 4 lines between those
> bitmaps .I should have a data structure which would contain the
> position of the itmes I have drawn, the size etc. And I will keep on
> addding new items to this pool.
> I think I ll have to impliment this mechanism in document also. Then
> draw these items everytime in the WM_PAINT handler or my OnDraw()
> function.
> For a big GDI application I think this would be very critical as the
> speed of the application depends on this.
> Is there any optimal mechanism to impliment this? if I use GDI+ would
> this implimentation change?
> Please throw some light on this ..

If you are doing something on the line of a 'scope' output, I recall
some stuff on codeproject that didn't look bad.

I don't know, but have you downloaded those examples?

Best, Dan.

 
 
ggurubasavaraja





PostPosted: Wed Aug 22 04:09:30 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . Hi Dan,

I did not get ur first statement ..
anyways I have downloaded many examples , but few are very complex and
some examples does not address this issue..

regards,
JustLikeDat

 
 
Les





PostPosted: Wed Aug 22 05:16:27 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC .


> Hi Dan,
>
> I did not get ur first statement ..

'scope' = Oscilliscope

Les


 
 
ggurubasavaraja





PostPosted: Wed Aug 22 06:27:18 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . Dan,

I did not find any sample of that type.
It would be great if you paste a link to that sample.

Regards,
JLD


 
 
AliR





PostPosted: Wed Aug 22 10:43:18 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . http://www.codeproject.com/miscctrl/oscope.asp


AliR.



> Dan,
>
> I did not find any sample of that type.
> It would be great if you paste a link to that sample.
>
> Regards,
> JLD
>
>


 
 
ggurubasavaraja





PostPosted: Wed Aug 22 23:40:37 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . Thanks a ton AliR

 
 
Joseph





PostPosted: Thu Aug 23 00:23:10 CDT 2007 Top

MFC >> Drawing continuously(dynamically) in MFC . The key here is that you never actually draw anything on the window from anywhere except
the OnPaint handler. Therefore, it is essential that you have some data structure of some
sort (the exact details always depend upon the nature of the application) which contains
all the information you need to completely draw everything you want on the window. To
update the display, you add new stuff, and Invalidate the window (or as small a piece of
the window as you can manage).

So indeed you would do as you describe. The most common way to handle this is to create a
single abstract superclass

class DrawingObject {
public:
virtual void Plot(CDC & dc) PURE;
};

Now you would have some structure of DrawingObjects, for simplicity, let's use a CArray:

CArray<DrawingObject *, DrawingObject *> DisplayList;

then you write OnPaint as

void CMyClass::OnPaint()
{
CPaintDC dc(this);
for(INT_PTR i = 0; i < DisplayList.GetSize(); i++)
DisplayList[i]->Plot(dc);
}

or OnDraw as

void CMyClass::OnDraw(CDC * pDC)
{
for(INT_PTR i = 0; i < DisplayList.GetSize(); i++)
DisplayList[i]->Plot(*pDC);
}

now you can derive classes, e.g.,

class CDrawingBitmap : public CDrawingObject {
public:
virtual void Plot(CDC & dc);
CPoint pt;
CBitmap bmp;
};

void CDrawingBitmap::Plot(CDC & dc)
{
...set up memory DC, etc.
dc.BitBlt(pt.x, pt.y, bminfo.bmWidth, bminfo.bmHeight, &memDC, 0, 0, SRCCOPY);
}

class CDrawingLine : public CDrawingObject {
public:
CDrawingLine() { LPen.lopnStyle = PS_SOLID;
LPen.lopnWidth = 0;
LPen.lopnColor = RGB(0,0,0);
rop = R2_COPYPEN; }
virtual void Plot(CDC & dc);
CPoint pt0; // first endpoint
CPoint pt1; // second endpoint
LOGPEN LPen;
int rop;
};

void CDrawingLine::Plot(CDC & dc)
{
int save = dc.SaveDC();
CPen pen;
pen.CreatePenIndirect(&LPen);
dc.SelectObject(&pen);
dc.SetROP2(rop);
dc.MoveTo(pt0);
dc.LineTo(pt1);
dc.RestoreDC(save);
}

class CPolygon : public CDrawingObject {
public:
virtual void Plot(CDC & dc) PURE;
CPolygon() { LPen.lopnColor = ...etc...
LBrush.lbStyle = BS_SOLID;
LBrush.lbColor = RGB(0,0,0);
LBrush.lbHance = 0; // depends on style
}
CRect boundingbox;
LOGPEN LPen;
LOGBRUSH LBrush;
};

class CEllipse : public CPolygon {
public:
virtual void Plot(CDC & dc);
CEllipse() : CPolygon() { }
};

void CEllipse::Plot(CDC & dc)
{
int save = dc.SaveDC();
CPen pen;
pen.CreatePenIndirect(&LPen);
CBrush br;
br.CreateBrushIndirect(&LBrush);
dc.SelectObject(&br);
dc.SelectObject(&pen);
dc.Ellipse(&boundingbox);
dc.RestoreDC(save);
}

and so on. You can build much more complex class structures.


Note that this is analogous to a structure you might have in the document, but the
document might represent these in a more abstract way. For example, the document might
merely note that there are objects with connectivity. A->B->C, for example. But the View
logic you implement figures out that A is a transistor, B is a resistor, and C is a
capacitor, and given the screen space and layout rules, will create the actual display
list, select the bitmaps that represent a transistor, resistor, or capacitor (and these
might be localized, since there are alternative representations of these components; in
spite of the apparent standardization, I remember that European schematics were harder to
read than the American ones I was familiar with. And reading a relay circuit diagram for
industrial controls, or for phone switching controls, requires reading entirely different
symbols than classic "relay" symbols used in other contexts. So what bitmaps you use to
represent whatever you are representing might change depending on locale). The view would
have information about the local implementation; the document would contain the abstract
specification of your diagram. Note that the document might implement semantics about the
objects, but the view has only information about how they are displayed.

Largely, the representation of objects like this hasn't changed since SketchPad was done
by Ivan Sutherland in 1961. I've used these kinds of representations on PDP-11 graphics
controllers, on Z80s with 80x80 LCD panels, on MS-DOS, on the Macintosh, and in every
version of Windows. GDI+ can add interesting parameters such as alpha blending, but the
basic concept doesn't change. You can use a CArray, std::vector, CList, std::list, etc.
to hold these objects, but the basic idea doesn't change at all.
joe



>Thanks a lot for ur replies.
>
>I think I undesrstood how to draw continuously onto a screen (window/
>view) . But I dont have any idea about how to store what I have
>drawn.
>Say for example I have drawn 3 bitmaps and 4 lines between those
>bitmaps .I should have a data structure which would contain the
>position of the itmes I have drawn, the size etc. And I will keep on
>addding new items to this pool.
>I think I ll have to impliment this mechanism in document also. Then
>draw these items everytime in the WM_PAINT handler or my OnDraw()
>function.
>For a big GDI application I think this would be very critical as the
>speed of the application depends on this.
>Is there any optimal mechanism to impliment this? if I use GDI+ would
>this implimentation change?
>Please throw some light on this ..
>
Joseph M. Newcomer [MVP]

Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm