From: Stephen Myers on
Luigino wrote:
> Hello again Joe and Stephen,
>
> I've corrected whatever you suggested to, Joe, made a Create() method
> to initialize, removed the OnCreate and the rest of stuffs...
>
> Stephen, I modified also the OnPaint() thing as you said as you can
> see below:
>
> void CCaChart::OnPaint()
> {
> CPaintDC dc(this); // device context for painting
> dc.SetBkColor(RGB(0,0,0));
>
> CRect rect;
> GetClientRect(&rect);
>
> int save = dc.SaveDC();
>
> if(bSetDraw)
> {
> CMemDC mDC(&dc);
>
> //mDC.SetBkColor(RGB(0,0,0));
> mDC.SetMapMode(MM_ANISOTROPIC);
> mDC.SetWindowOrg(rect.BottomRight());
> mDC.SetViewportOrg(0, 0);
> mDC.SetViewportExt(-1, -1);
> //mDC.SetViewportExt(-rect.right, -rect.bottom);
> mDC.SetWindowExt(1, 1);
> //mDC.SetWindowExt(rect.Width(), rect.Height());
> // ********** Background ***********
> // Grid
> if (bActivateGrid)
> {
> CPen qLinePen(PS_SOLID, 1, RGB(0,139,0));
> mDC.SelectObject(&qLinePen);
>
> // Grid - Horizontal lines
> mDC.MoveTo(1, 0);
> mDC.LineTo(rect.Width(), 0);
> int height = rect.Height();
> int maxlines = height / (int)12.5;
> for (int i=1;i<=maxlines;i++){
> int y_axis = (int)((double)i * 12.5);
> if (y_axis <= rect.Height()) {
> mDC.MoveTo(1, y_axis);
> mDC.LineTo(rect.Width(),
> y_axis);
> }
> }
>
> // Grid - Vertical lines
> mDC.MoveTo(0, 0);
> mDC.LineTo(0, rect.Height());
> int width = rect.Width();
> maxlines = width / (int)12.5;
> for (int i=1;i<=maxlines;i++){
> int x_axis = (int)(((double)i * 12.5)
> - gridOffset);
> if (x_axis <= rect.Width()) {
> mDC.MoveTo(x_axis, 1);
> mDC.LineTo(x_axis,
> rect.Height());
> }
> }
>
> qLinePen.DeleteObject();
> }
> // *********** graphic component ***********
> // based on choice of graph type
> CPen qPolylinePen(PS_SOLID, 1, RGB(0, 255, 0));
> switch (iGraphType)
> {
> case GRAPH_BARS:
> break;
>
> case GRAPH_LINES:
> {
> if (vtPoints.capacity() == 1)
> {
>
> mDC.SelectObject(qPolylinePen);
> vectfPoints* pointsline =
> &vtPoints[0];
> mDC.Polyline(&(*pointsline)
> [0], (int)pointsline->size());
> //mDC->PolyPolyline()
> qPolylinePen.DeleteObject();
> }
> }
> break;
>
> default:
> break;
> }
> GDI_FLUSH();
> }
>
> dc.RestoreDC(save);
> }
>
> but when I resize window the vertical and horizontal lines are
> repainted to the whole canvas but the Polyline stuff isn't rescaled; I
> mean I have values in the vtPoints array which MM_ANISOTROPIC should
> rescale automatically due having set SetViewportExt and SetWindowExt
> respectively to -1, -1 and 1, 1 so I guess it should scale 1:1 and the
> polyline graphic should be adjusted when resizing window....but it
> doesn't... what I could have missed or made wrong in those
> SetViewportExt and SetWindowExt?...
>
> Thanks
> Ciao
> Luigi


Your problem is with the (over) use of rect. You don't need it anywhere
except to initialize the CDC's mapping.

You do not care what the size of the rectangle on the screen is. You
want your drawing to fill the rectangle.

Ignoring the mapping calls, you want to be able to do the equivalent of
MoveTo(1,2); LineTo(7,3). The MoveTo and LineTo parameters do not
change based on the screen coordinates. You're going to let the CDC
manage that. This allows you to collect the data in quantities that
make sense to you without regard for the underlying screen resolution.


SetWindowExt is in logical units.
SetViewportExt is in screen units.

All your drawing is then in logical units.

It will make it easier to debug if you draw your gridlines in logical
units. Or just draw a line from one corner diagonally across to the
opposite corner. When that's working properly, adding the polyline
should be easy.

Steve
From: Joseph M. Newcomer on
See below...
On Fri, 5 Feb 2010 08:47:48 -0800, "James Juno" <juno(a)noplace.fake> wrote:

>Joe,
>
>Along these lines, would the following snippet leak a GDI resource?
>
>void CMyCWnd::OnPaint()
>{
> CPaintDC dc( this );
> const int dcState = dc.SaveDC();
>
> dc.SelectObject( &m_pen ); // m_pen was created elsewhere in object scope
>
> // ... draw something
>
> dc.SelectStockObject( BLACK_PEN ); // m_pen selected out of DC?
****
At this point, since m_Pen is no longer selected into a DC context, the DeleteObject which
follows *will* delete the object
****
> m_pen.DeleteObject();
> m_pen.CreatePen( ... ); // recreate with new parameters
> dc.SelectObject( &m_pen );
****
This works. I find it a big ugly to keep reusing the same pen variable like this, since
the reason for making it non-local would be that it only needs to be created once (a
common practice, by the way).
****
>
> // ... draw something else
>
> dc.RestoreDC( dcState );
****
The DC itself is destroyed at this point when it goes out of scope, so what is selected
into it will no longer matter.
joe
****
>}
>
>Much thanks,
>JJ
>
>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
>news:g5bom51cb8enn8v2vur9idaubcm77bncot(a)4ax.com...
>> See below...
>> On Fri, 5 Feb 2010 03:57:31 -0800 (PST), Luigino <npuleio(a)rocketmail.com>
>> wrote:
>>...
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Luigino on
Hello Stephen....

then since as you said I should set SetWindowExt and SetViewportExt in
their respective unit and since I'm drawing the whole GetClientRect so
how I should set them to make automatically re-scaling when
repainting?....

Thanks
Ciao
Luigi
From: Luigino on
Hello Joe,

> How do you mean "not rescaled"?  How do you know that?  Perhaps because the lines don't
> appear?  If so, that is not surprising, since I don't see any place at which the bitmap in
> the memDC is transferred to the dc.  Also, I don't see where you are actually setting the
> scale, since the points you are recording cannot be prescaled; they have to be "raw" data,
> since by the time they are displayed, the size of the window in which they are displayed
> can change.

About not rescaled I mean this:

http://img707.imageshack.us/img707/3444/44318805.jpg <---- this is the
control minimized

http://img16.imageshack.us/img16/4699/64174798.jpg <---- this is the
control maximized

As you can see the initial part of the graphic should be bigger,
indeed looks rescaled the second part...

Thanks
Ciao
Luigi
From: Stephen Myers on


"Luigino" wrote:

> Hello Stephen....
>
> then since as you said I should set SetWindowExt and SetViewportExt in
> their respective unit and since I'm drawing the whole GetClientRect so
> how I should set them to make automatically re-scaling when
> repainting?....
>
> Thanks
> Ciao
> Luigi
> .
>
Something like:
m_MemDC.SetMapMode(MM_ANISOTROPIC);
m_MemDC.SetWindowExt(m_MaxTime, m_nVMaxY);
m_MemDC.SetViewportOrg(0, rect.Height());
m_MemDC.SetWindowOrg(0,0);
m_MemDC.SetViewportExt(rect.Width(),-rect.Height());
m_MemDC.SelectObject(&m_VPen);
m_MemDC.Polyline(&m_VMinPts[0],(int)m_VMinPts.size());

rect is the screen rect.
m_VMinPts is a std::vector<CPoint>

m_MemDC is a memory CDC. In my application, m_MemDC can be created as part
of OnInitDialog(). (I don't have to worry about resizing.) This code is
actually from DrawItem of a owner draw control.

For each data point I add a CPoint where X is time in milliseconds, and Y is
the measurement of interest, on the range [0, m_nVMaxY].

HTH
Steve