about Coordinate Map Mode and compatible DC ???
-
How to change the Coordinate Map Mode ,create a compatible DC used to draw ,then call bitblt() to show the picture? my code in the following , But when I run it ,there is nothing to be showed! void CTestSetMapModeView::OnLButtonDown(UINT nFlags, CPoint point) { CRect rect; GetClientRect(rect); CClientDC dc (this); dc.SetMapMode (MM_ISOTROPIC); dc.SetWindowExt (rect.Width (), -rect.Height ()); dc.SetViewportExt (rect.Width (), -rect.Height ()); dc.SetViewportOrg (point); CDC memDC; memDC.CreateCompatibleDC(&dc); memDC.SetMapMode(MM_ISOTROPIC); memDC.SetWindowExt(rect.Width(), -rect.Height()); memDC.SetViewportExt(rect.Width(), -rect.Height()); memDC.SetViewportOrg (point); CBitmap bitmap,*pOldBitmap; bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height()); pOldBitmap=memDC.SelectObject(&bitmap); memDC.BitBlt(-rect.Width()/2,rect.Height()/2,rect.Width(),rect.Height(),&dc,-rect.Width()/2,rect.Height()/2,SRCCOPY); //draw some pictures memDC.Ellipse(-50,50,50,-50); memDC.Ellipse(-10,20,10,-20); dc.BitBlt(-rect.Width()/2,rect.Height()/2,rect.Width(),rect.Height(),&memDC,-rect.Width()/2,rect.Height()/2,SRCCOPY ); memDC.SelectObject(pOldBitmap); bitmap.DeleteObject(); CView::OnLButtonDown(nFlags, point); }
Antonlio, One thing I've found interesting about Windows Programming is the level of filtering Win32 does that is quite invisible. In this case, Win32 contains some code that says "ignore all drawing unless I need to draw..." Windows makes the decision to draw if the window is invalid. If you invalidate the target window, windows will fire an On Paint message. Adjust your code accordingly, and all will be well (at least you should see something on the screen). chg C. Gilley Will program for food... Whoever said children were cheaper by the dozen... lied.
-
Antonlio, One thing I've found interesting about Windows Programming is the level of filtering Win32 does that is quite invisible. In this case, Win32 contains some code that says "ignore all drawing unless I need to draw..." Windows makes the decision to draw if the window is invalid. If you invalidate the target window, windows will fire an On Paint message. Adjust your code accordingly, and all will be well (at least you should see something on the screen). chg C. Gilley Will program for food... Whoever said children were cheaper by the dozen... lied.
I think the problem in my case is the " coordinate map ". I don't know When I excute the following codes: CRect rect; GetClientRect(rect); CClientDC dc (this); dc.SetMapMode (MM_ISOTROPIC); dc.SetWindowExt (rect.Width (), -rect.Height ()); dc.SetViewportExt (rect.Width (), -rect.Height ()); dc.SetViewportOrg (point); , Whether I should also change the memDC's coordinate map mode ,just like the following : CDC memDC; memDC.CreateCompatibleDC(&dc); memDC.SetMapMode(MM_ISOTROPIC); memDC.SetWindowExt(rect.Width(), -rect.Height()); memDC.SetViewportExt(rect.Width(), -rect.Height()); memDC.SetViewportOrg (point); aa
-
I think the problem in my case is the " coordinate map ". I don't know When I excute the following codes: CRect rect; GetClientRect(rect); CClientDC dc (this); dc.SetMapMode (MM_ISOTROPIC); dc.SetWindowExt (rect.Width (), -rect.Height ()); dc.SetViewportExt (rect.Width (), -rect.Height ()); dc.SetViewportOrg (point); , Whether I should also change the memDC's coordinate map mode ,just like the following : CDC memDC; memDC.CreateCompatibleDC(&dc); memDC.SetMapMode(MM_ISOTROPIC); memDC.SetWindowExt(rect.Width(), -rect.Height()); memDC.SetViewportExt(rect.Width(), -rect.Height()); memDC.SetViewportOrg (point); aa
-
The aim of my case is to paint picture in the memory-DC (compatible DC) ,for preventing glitter when refresh(repaint)! And I choose the maths coordinate mode not the MM_TEXT .That is X-axis ascending from left to righgt while Y-axis from bottom to top!
Antonlio, My exposure to date with Win32 is through Windows CE, and Windows CE does not support the different mapping modes. I cannot comment further regarding that issue. I understand what you are doing - it's called double buffering and a host of other names. What I would do is divide and reduce the issue. Just add some code that slaps something silly onto the page in the default mode. If that doesn't show up, it isn't your scaling, it's what I mentioned earlier... C. Gilley Will program for food... Whoever said children were cheaper by the dozen... lied.
-
Antonlio, My exposure to date with Win32 is through Windows CE, and Windows CE does not support the different mapping modes. I cannot comment further regarding that issue. I understand what you are doing - it's called double buffering and a host of other names. What I would do is divide and reduce the issue. Just add some code that slaps something silly onto the page in the default mode. If that doesn't show up, it isn't your scaling, it's what I mentioned earlier... C. Gilley Will program for food... Whoever said children were cheaper by the dozen... lied.
-
CharlieG : Thank you very much ! I have solved this question by now ,the key of which is the ordinate of the MemDC should be set correct . Antonliox
-
The aim of my case is to paint picture in the memory-DC (compatible DC) ,for preventing glitter when refresh(repaint)! And I choose the maths coordinate mode not the MM_TEXT .That is X-axis ascending from left to righgt while Y-axis from bottom to top!
Drawing inside
OnLButtonDown()
is not a good approach. All drawing should be done inYourView::OnDraw()
, based on the document's content, and possibly some state you keep inYourView
. AtOnLButtonDown()
, or for that matter, at the handler of any command that represents user interaction, you should alter the data in the document or the state of your view. If you alter the document, you should make the document notify the views about that fact (seeCDocument::UpdateAllViews()
). The view receives the document's notifications throughOnUpdate()
. The notification may include additional data that narrows what kind of modification was done and to what extent, so that each view can optimize the work needed to update the drawing. In the more general case, the view just callsInvalidate()
, so as to redraw the entire window next timeOnDraw()
is invoked. Depending on the hint received, it may go for invalidating only a portion of the drawing. Going back toOnDraw()
, you can just draw everything (Windows will only update the invalidated portions of the window, anyway), or you may optimize the drawing by excluding portions of the drawing you know are out of the visible portion of the window, or are not invalidated. Now, the best place to deal with mapping modes is atYourView::OnPrepareDC()
, which the framework will always call before callingYourView::OnDraw
. Drawing to an offscreen bitmap to avoid flickering can be done, for example, in the following way. It's based in some working code but since I modified it for this post and haven't actually tested it, I can't guarantee that it works or even that it compiles, but I hope it helps, anyway:void CYourView::OnDraw(CDC* pDC)
{
CDC dc;
CDC* pDrawDC = pDC;
CBitmap bitmap;
CBitmap* pOldBitmap = NULL;
CRect client;
if (pDC->GetClipBox(client) == NULLREGION)
return; // no need to draw
CRect rect = client;
dc.LPtoDP(rect)
if (!pDC->IsPrinting())
{
// draw to offscreen bitmap for fast looking repaints
if (dc.CreateCompatibleDC(pDC))
{
if (bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()))
{
OnPrepareDC(&dc, NULL);
pDrawDC = &dc;
// offset origin because bitmap is just
// a piece of the whole drawing
dc.OffsetViewportOrg(-rect.left, -rect.top);
pOldBitmap = dc.SelectObject(&bitmap);
dc.SetBrush -
Drawing inside
OnLButtonDown()
is not a good approach. All drawing should be done inYourView::OnDraw()
, based on the document's content, and possibly some state you keep inYourView
. AtOnLButtonDown()
, or for that matter, at the handler of any command that represents user interaction, you should alter the data in the document or the state of your view. If you alter the document, you should make the document notify the views about that fact (seeCDocument::UpdateAllViews()
). The view receives the document's notifications throughOnUpdate()
. The notification may include additional data that narrows what kind of modification was done and to what extent, so that each view can optimize the work needed to update the drawing. In the more general case, the view just callsInvalidate()
, so as to redraw the entire window next timeOnDraw()
is invoked. Depending on the hint received, it may go for invalidating only a portion of the drawing. Going back toOnDraw()
, you can just draw everything (Windows will only update the invalidated portions of the window, anyway), or you may optimize the drawing by excluding portions of the drawing you know are out of the visible portion of the window, or are not invalidated. Now, the best place to deal with mapping modes is atYourView::OnPrepareDC()
, which the framework will always call before callingYourView::OnDraw
. Drawing to an offscreen bitmap to avoid flickering can be done, for example, in the following way. It's based in some working code but since I modified it for this post and haven't actually tested it, I can't guarantee that it works or even that it compiles, but I hope it helps, anyway:void CYourView::OnDraw(CDC* pDC)
{
CDC dc;
CDC* pDrawDC = pDC;
CBitmap bitmap;
CBitmap* pOldBitmap = NULL;
CRect client;
if (pDC->GetClipBox(client) == NULLREGION)
return; // no need to draw
CRect rect = client;
dc.LPtoDP(rect)
if (!pDC->IsPrinting())
{
// draw to offscreen bitmap for fast looking repaints
if (dc.CreateCompatibleDC(pDC))
{
if (bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()))
{
OnPrepareDC(&dc, NULL);
pDrawDC = &dc;
// offset origin because bitmap is just
// a piece of the whole drawing
dc.OffsetViewportOrg(-rect.left, -rect.top);
pOldBitmap = dc.SelectObject(&bitmap);
dc.SetBrush -
AntonlioX wrote: Thank you very much .What you have said is much useful ! You are welcome! Glad to be of help. -- jlr http://jlamas.blogspot.com/[^]
-
AntonlioX wrote: Thank you very much .What you have said is much useful ! You are welcome! Glad to be of help. -- jlr http://jlamas.blogspot.com/[^]
Hi, Iam using Keith Rule's CMemDc class & I have changed it according to my requirement.Iam posting that class also here. Now Iam zooming my View using "SetWorldTransform" call. My problem now is when I change the zoom factor to below or above 100,the Fonts are not smooth. The following are my codes: //Creating Font like this in "MyView" constructor.Don't want to use FixedFonts. m_oFont.CreatePointFont(120, _T("Courier New")); LOGFONT oLogfont; m_oFont.GetLogFont(&oLogfont); //OnPrepareDc looks like this. void MyView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { pDC->SetMapMode(MM_TEXT); SetGraphicsMode(pDC->GetSafeHdc(), GM_ADVANCED); pDC->SelectObject(&m_oFont); pDC->GetTextMetrics(&m_TextMetrics); XFORM xForm; xForm.eM11 = 0.01 * m_iZoomFactor; xForm.eM21 = 0; xForm.eDx = 0; xForm.eM12 = 0; xForm.eM22 = 0.01 * m_iZoomFactor; xForm.eDy = 0; pDC->GetTextMetrics(&m_textMetrics); SetWorldTransform(pDC->GetSafeHdc(), &xForm); CScrollView::OnPrepareDC(pDC, pInfo); } //My "OnDraw" looks like this. void MyView::OnDraw(CDC* pDC) { CpagesDoc* pDoc = GetDocument(); CSize sizeTotal; //default scrollsizes to 80 chars X 80 lines. sizeTotal.cx = 80; sizeTotal.cy = 80; //Client Rectangle Size. CRect rect; GetClientRect(&rect); //Creating a temporary Dc. C_TempDc tempDC(pDC,m_oFont,&rect); int pageWidth = 800; int pageHeight = 800; //int pageGap = 5; int pageNumber =3; SIZE size; size.cx = 1000; size.cy = (pageHeight*3)+100; //First Page tempDC->Rectangle(CRect(0,0,pageWidth,pageHeight)); tempDC->TextOut(5,10,"This is the first line on the FirstPage"); sizeTotal.cx *= MulDiv(m_textMetrics.tmAveCharWidth, m_iZoomFactor, 100); sizeTotal.cy *= MulDiv(m_textMetrics.tmHeight, m_iZoomFactor, 100); SetScrollSizes(MM_TEXT, sizeTotal); } //Keith Rule's Memory Buffer #ifndef C_TEMPDC_H #define C_TEMPDC_H class C_TempDc : public CDC { public: C_TempDc(CDC* pDC,CFont & font,const CRect* pRect = NULL): CDC() { ASSERT(pDC != NULL); //Initialising. m_pDC = pDC; m_oldBitmap = NULL; m_oldFont= NULL; //Getting ClipBox Rectangle. pDC->GetClipBox(&m_clipRect); //Client Rectangle. m_clientRect = *pRect; pDC->DPtoLP(&m_clientRect); // Create a Memory DC CreateCompatibleDC(pDC); //pDC->LPtoDP(&m_rect); m_bitmap.CreateCompatibleBitmap(pDC,m_clientRect.Width(),m_cli