Re: PolyLine and autoscrolling canvas
Luigino wrote:
HI Joe,
I figured to draw correctly horizontal scrolling having origin point
at right bottom so the graphic starts from right to left but it
flickers.
So I created a memory DC with CreateCompatibleDC but looks like memory
dc doesn't behave really the same about mapping as you can see in this
code:
void CMyDLL::PrepareDC(CDC & dc, CRect rc)
{
dc.SetMapMode(MM_ANISOTROPIC);
switch (iGraphType)
{
case GRAPH_BARS:
{
//dc.Rectangle()
}
break;
case GRAPH_LINES:
{
dc.SetWindowExt(-rc.Width(), iYMaxInterval);
dc.SetViewportExt(rc.Width(), -rc.Height());
dc.SetWindowOrg(rc.Width(), 0);
dc.SetViewportOrg(0, rc.Height());
}
break;
default:
break;
}
}
void CMyDLL::DoDrawing(CDC & dc, CRect rc)
{
// *********** graphic component ***********
// based on choice of graph type
CPen qPolylinePen(PS_SOLID, 1, RGB(0, 255, 0));
switch (iGraphType)
{
case GRAPH_BARS:
{
//dc.Rectangle()
}
break;
case GRAPH_LINES:
{
if (vtPoints.capacity() == 1)
{
for (int i=vtPoints[0].size()-1;i>=0;i--) {
vtToDraw[0].at(i).x = vtPoints[0].at(i).x;
vtToDraw[0].at(i).y = ( (vtPoints[0].at(i).y > 0) ?
vtPoints[0].at(i).y : 86 );
}
dc.SelectObject(qPolylinePen);
vectfPoints* pointsline = &vtToDraw[0];
dc.Polyline(&(*pointsline)[0], (int)pointsline->size());
//dc.PolyPolyline()
}
}
break;
default:
break;
}
GDI_FLUSH();
}
void CNyDLL::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect r;
dc.GetClipBox(&r);
dc.SetBkColor(RGB(0,0,0));
int saveobject = dc.SaveDC();
if(bSetDraw)
{
// ********** Background ***********
// Grid
if (firstTime) {
PrepareDC(dc, r);
firstTime = FALSE;
}
CDC memDC;
CBitmap bBitmap; // Offscreen bitmap
CBitmap* bOldBitmap; // bitmap originally found
memDC.CreateCompatibleDC(&dc);
bBitmap.CreateCompatibleBitmap(&dc, r.Width(), r.Height());
bOldBitmap = memDC.SelectObject(&bBitmap);
memDC.FillSolidRect(r, dc.GetBkColor());
memDC.SetMapMode(dc.GetMapMode());
memDC.SetWindowExt(dc.GetWindowExt());
memDC.SetViewportExt(dc.GetViewportExt());
memDC.SetWindowOrg(dc.GetWindowOrg());
memDC.SetViewportOrg(dc.GetViewportOrg());
if (bActivateGrid)
{
CPen qLinePen(PS_SOLID, 0, RGB(0,139,0));
memDC.SelectObject(qLinePen);
// Grid - Horizontal lines
for(int y = 0; y < r.bottom; y += (int)12) {
/* scan y */
memDC.MoveTo(r.left, y);
memDC.LineTo(r.right, y);
} /* scan y */
// Grid - Vertical lines
for(int x = 0 - (int)gridOffset; x <= r.right - (int)gridOffset; x
+= (int)12 ) {
/* scan x */
memDC.MoveTo(x, r.top);
memDC.LineTo(x, r.bottom);
} /* scan x */
}
DoDrawing(memDC, r);
// Copy the offscreen bitmap onto the screen.
dc.BitBlt(r.left, r.top, r.Width(), r.Height(),
&memDC, r.left, r.top, SRCCOPY);
//Swap back the original bitmap.
memDC.SelectObject(bOldBitmap);
}
//}
dc.RestoreDC(saveobject);
}
because the PolyLine now starts from left to rigtht and on the other
hand it looks like it doesn't apply correctly the Y interval...
Did I maybe forgot something or is there a possible alternative to
avoid flickering if CreateCompatibleDC isn't the right solution for
this?...
Thanks,
Ciao
Luigi
Luigi,
Assume that anytime a DC is created or passed as a parameter, that it is
in MM_TEXT. Your mapping is only valid for the life of the object. In
particular, your OnPaint() assumes (incorrectly) that the mapping done
in PrepareDC is only required one time. Each time you create a DC you
must do the mappings.
Having said that, why bother changing the mapping of DC at all? The CDC
that you want to map is memDC. So call PrepareDC(memDC, r) each time
through.
You will then want to memDC.SetMapMode(MM_TEXT) immediately prior to
doing the bitblt.
Steve