Why SetViewportOrg can not work for Memory DC?

The following is a simple code. The class CSrlBufBarView derived from CScrollView. If we delete the line dcMem.SetViewportOrg(ptImgPos + dcMem.GetViewportOrg());

- just don't call SetViewportOrg for Memory DC, it's OK. But when I call SetViewportOrg, painting is error.

void CSrlBufBarView::OnPaint()
{
CPaintDC dc(this);
OnPrepareDC(&dc);
CDC *pDC = &dc;
TRACE("viewport of dc is (%d, %d).\n",
dc.GetViewportOrg().x,
dc.GetViewportOrg().y);

// draw in buffer
CRect rectClipBox;
if (pDC->GetClipBox(&rectClipBox) == ERROR)
{
AfxMessageBox(_T("CTestView::GetDC from CTestView::OnDraw failed!"), MB_OK);
return;
}
TRACE("clipbox is (%d, %d, %d, %d).\n",
rectClipBox.left,
rectClipBox.top,
rectClipBox.right,
rectClipBox.bottom);

//create display buffer
CBitmap ddb;
if (!ddb.CreateCompatibleBitmap(pDC, rectClipBox.Width(), rectClipBox.Height()))
{
AfxMessageBox(_T("CBitmap::CreateCompatibleBitmap from CTestView::OnDraw failed!"), MB_OK);
return;
}

CDC dcMem;
if (!dcMem.CreateCompatibleDC(pDC))
{
AfxMessageBox(_T("CDC::CreateCompatibleDC from CTestView::OnDraw failed!"), MB_OK);
return;
}
CBitmap *pOldDDB = dcMem.SelectObject(&ddb);
TRACE("viewport of dcMem is (%d, %d).\n",
dcMem.GetViewportOrg().x,
dcMem.GetViewportOrg().y);

CRect rect(0, 0, rectClipBox.Width(), rectClipBox.Height());
dcMem.FillSolidRect(rect, pDC->GetBkColor());
TRACE("dcMem bitmap rect is (%d, %d, %d, %d).\n",
rect.left,
rect.top,
rect.right,
rect.bottom);

CPoint ptImgPos(
-rectClipBox.left,
-rectClipBox.top);
TRACE("offset of image is (%d, %d).\n",
ptImgPos.x,
ptImgPos.y);

dcMem.MoveTo(ptImgPos.x, ptImgPos.y);
dcMem.LineTo(500 + ptImgPos.x, 500 + ptImgPos.y);

dcMem.SetViewportOrg(ptImgPos + dcMem.GetViewportOrg());
TRACE("viewport of dcMem is (%d, %d).\n",
dcMem.GetViewportOrg().x,
dcMem.GetViewportOrg().y);
dcMem.MoveTo(0, 0);
dcMem.LineTo(500, 500);

//OnDraw(&dcMem);


//copy memory dc to device dc
if (!pDC->BitBlt(
rectClipBox.left,
rectClipBox.top,
rectClipBox.Width(),
rectClipBox.Height(),
&dcMem,
0,
0,
SRCCOPY))
{
AfxMessageBox(_T("CDC::BitBlt from CTestView::OnDraw failed!"), MB_OK);
dcMem.SelectObject(pOldDDB);
return;
}

dcMem.SelectObject(pOldDDB);
TRACE("\n");
}



Answer this question

Why SetViewportOrg can not work for Memory DC?

  • Benedikt

    I am not sure. I just guess.

    Reset the view port org on the mem dc back to the previous values. Otherwise the coordinates used by the following BitBlt are interpreted by this coordinates too.



  • jPolizzi

    Oh, stupid me. It's done. Thank you very much.
  • Why SetViewportOrg can not work for Memory DC?