From: Luigino on 23 Feb 2010 12:50 HI Stephen, > What happens with > memDC.SetMapMode(MM_TEXT); > dc.BitBlt(0,0,r.Width(),r.Height(),&memDC,0,0,SRCCPY); > > ??? > Both memDC and dc are then using MM_TEXT, have the same size bitmaps, so > this should work. Is there something going on with bSetDraw? > > Steve > > > //Swap back the original bitmap. > > memDC.SelectObject(bOldBitmap); > > } > > ... Figured out right a bit ago.... had to do: 1) put the grid drawing BEFORE the mapping 2) adding: memDC.SetWindowOrg(0, 0); memDC.SetViewportOrg(0, 0); to re-set the point origin, probably because even if setting MM_TEXT the point origin won't be reset to (0,0)...so the right OnPaint() structure is this: void CGraphClass::OnPaint() { CPaintDC dc(this); // device context for painting CRect r; GetClientRect(&r); dc.SetBkColor(RGB(0,0,0)); int saveobject = dc.SaveDC(); if(bSetDraw) { // ********** Background *********** // Grid CDC memDC; CBitmap bBitmap; // Offscreen bitmap CBitmap* bOldBitmap; // bitmap originally found in CMemDC memDC.CreateCompatibleDC(&dc); bBitmap.CreateCompatibleBitmap(&dc, r.right, r.bottom); bOldBitmap = memDC.SelectObject(&bBitmap); memDC.FillRect(r, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); if (bActivateGrid) { CPen qLinePen(PS_SOLID, 1, 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 */ } memDC.SetMapMode(MM_ANISOTROPIC); memDC.SetWindowExt(-r.right, iYMaxInterval); memDC.SetViewportExt(r.right, -r.bottom); memDC.SetWindowOrg(r.right, 0); memDC.SetViewportOrg(0, r.bottom); 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 ); } //int savedraw = memDC.SaveDC(); CPen qPolylinePen(PS_SOLID, 1, RGB(0, 255, 0)); memDC.SelectObject(qPolylinePen); vectfPoints* pointsline = &vtToDraw[0]; memDC.Polyline(&(*pointsline)[0], (int)pointsline->size()); //dc.PolyPolyline() //memDC.RestoreDC(savedraw); } // Copy the offscreen bitmap onto the screen. memDC.SetMapMode(MM_TEXT); memDC.SetWindowOrg(0, 0); memDC.SetViewportOrg(0, 0); // DC isn't altered about mapping!! so it should SRCCOPY as like as the bitmap appears dc.BitBlt(r.left, r.top, r.right, r.bottom, &memDC, r.left, r.top, SRCCOPY); //Swap back the original bitmap. memDC.SelectObject(bOldBitmap); } dc.RestoreDC(saveobject); } Now I have to implement the vertical bars which it should be a bit easier I think... at least there's always this place where to find hints :-) Thanks a lot for now Ciao Luigi
From: Joseph M. Newcomer on 23 Feb 2010 14:53 See below... On Tue, 23 Feb 2010 09:50:52 -0800 (PST), Luigino <npuleio(a)rocketmail.com> wrote: >HI Stephen, > >> What happens with >> memDC.SetMapMode(MM_TEXT); >> dc.BitBlt(0,0,r.Width(),r.Height(),&memDC,0,0,SRCCPY); >> >> ??? >> Both memDC and dc are then using MM_TEXT, have the same size bitmaps, so >> this should work. Is there something going on with bSetDraw? >> >> Steve >> >> > //Swap back the original bitmap. >> > memDC.SelectObject(bOldBitmap); >> > } >> >> ... > >Figured out right a bit ago.... had to do: > >1) put the grid drawing BEFORE the mapping >2) adding: > > memDC.SetWindowOrg(0, 0); > memDC.SetViewportOrg(0, 0); *** Note that you can nest SaveDC/RestoreDC. You have to retain the bitmap, so it would be int save1 = memDC.SaveDC(); memDC.SelectObject(&bitmap); ...draw grid int save2 = memDC.SaveDC(); ...set coordinate mapping mode parameters ....do drawing memDC.RestoreDC(save2); ... back in MM_TEXT mode with everything reset except the bitmap dc.BitBlt(...); memdc.RestoreDC(save1); No need to keep resetting things one at a time. It only becomes confusing. joe ***** > >to re-set the point origin, probably because even if setting MM_TEXT >the point origin won't be reset to (0,0)...so the right OnPaint() >structure is this: > >void CGraphClass::OnPaint() >{ > CPaintDC dc(this); // device context for painting > > CRect r; > GetClientRect(&r); > dc.SetBkColor(RGB(0,0,0)); > > int saveobject = dc.SaveDC(); > > if(bSetDraw) > { > // ********** Background *********** > // Grid > CDC memDC; > CBitmap bBitmap; // Offscreen >bitmap > CBitmap* bOldBitmap; // bitmap >originally found in CMemDC > > memDC.CreateCompatibleDC(&dc); **** int save1 = memDC.SaveDC(); **** > bBitmap.CreateCompatibleBitmap(&dc, r.right, >r.bottom); > bOldBitmap = memDC.SelectObject(&bBitmap); **** No reason whatsoever to save the old bitmap. Get rid of this variable, it serves no useful purpose. SaveDC/RestoreDC do everything you need! **** > > memDC.FillRect(r, >CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); > > if (bActivateGrid) > { **** The code below is incorrect because the destructor for the pen will try to destroy a pen selected into the DC. So you should have int save2 = memDC.SaveDC(); **** > CPen qLinePen(PS_SOLID, 1, 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 */ ***** And here you need memDC.RestoreDC(save2); so the pen is deselected ***** > } > **** { int save3 = memDC.SaveDC(); I prefer to use braces for proper scoping **** > memDC.SetMapMode(MM_ANISOTROPIC); > memDC.SetWindowExt(-r.right, iYMaxInterval); > memDC.SetViewportExt(r.right, -r.bottom); > memDC.SetWindowOrg(r.right, 0); > memDC.SetViewportOrg(0, r.bottom); > > 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 ); > } > //int savedraw = memDC.SaveDC(); > > CPen qPolylinePen(PS_SOLID, 1, RGB(0, 255, >0)); > memDC.SelectObject(qPolylinePen); > vectfPoints* pointsline = &vtToDraw[0]; > memDC.Polyline(&(*pointsline)[0], >(int)pointsline->size()); **** THis appears to be a clumsy way of saying *pointsline **** > //dc.PolyPolyline() > > //memDC.RestoreDC(savedraw); **** Note that without the saveDC/RestoreDC you are leaking pen resources. You will run out of GDI resources fairly soon. **** > } > > // Copy the offscreen bitmap onto the screen. **** memDC.RestoreDC(save3); } You keep trying to do this the hard way! Why? **** > memDC.SetMapMode(MM_TEXT); > memDC.SetWindowOrg(0, 0); > memDC.SetViewportOrg(0, 0); > > // DC isn't altered about mapping!! so it should >SRCCOPY as like as the bitmap appears > dc.BitBlt(r.left, r.top, r.right, r.bottom, > &memDC, r.left, r.top, >SRCCOPY); > > //Swap back the original bitmap. > memDC.SelectObject(bOldBitmap); **** No need! The following code does it more cleanly: memDC.RestoreDC(save1); You can use my SaveDC/RestoreDC class from my MVP Tips site to automate this! **** > } > dc.RestoreDC(saveobject); >} > >Now I have to implement the vertical bars which it should be a bit >easier I think... at least there's always this place where to find >hints :-) > >Thanks a lot for now >Ciao >Luigi Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Area Cinque on 24 Feb 2010 05:21 HI Joe, > **** > int save1 = memDC.SaveDC(); > ****> bBitmap.CreateCompatibleBitmap(&dc, r.right, > >r.bottom); > > bOldBitmap = memDC.SelectObject(&bBitmap); > > **** > No reason whatsoever to save the old bitmap. Get rid of this variable, it serves no > useful purpose. SaveDC/RestoreDC do everything you need! > **** I tried to get rid of saving old bitmap but then it doesn't show anything... using old bitmap indeed the image is present... (I have implemented also the SaveDC/RestoreDC stuffs)... maybe it's needed for old bitmap?... Thanks Ciao Luigi
From: Luigino on 24 Feb 2010 06:55
HI Joe, > **** > int save1 = memDC.SaveDC(); > ****> bBitmap.CreateCompatibleBitmap(&dc, r.right, > >r.bottom); > > bOldBitmap = memDC.SelectObject(&bBitmap); > > **** > No reason whatsoever to save the old bitmap. Get rid of this variable, it serves no > useful purpose. SaveDC/RestoreDC do everything you need! > **** I tried to get rid of old bitmap but it looks like it's necessary because without old bitmap it doesn't show anything on the form... Thanks Ciao Luigi |