From: Stephen Myers on 5 Feb 2010 11:04 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 5 Feb 2010 17:31 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 7 Feb 2010 16:55 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 7 Feb 2010 20:30 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 8 Feb 2010 00:36
"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 |