////////////////////////////////////////////////// // CMemDC - memory DC // // Author: Keith Rule // Email: keithr@europa.com // Copyright 1996-1997, Keith Rule // // You may freely use or modify this code provided this // Copyright is included in all derived versions. // // History - 10/3/97 Fixed scrolling bug. // Added print support. // // This class implements a memory Device Context
class CMemDC : public CDC { private: CBitmap m_bitmap; // Offscreen bitmap CBitmap* m_oldBitmap; // bitmap originally found in CMemDC CDC* m_pDC; // Saves CDC passed in constructor CRect m_rect; // Rectangle of drawing area. BOOL m_bMemDC; // TRUE if CDC really is a Memory DC. public: CMemDC(CDC* pDC) : CDC(), m_oldBitmap(NULL), m_pDC(pDC) { ASSERT(m_pDC != NULL); // If you asserted here, you passed in a NULL CDC.
m_bMemDC = !pDC->IsPrinting();
if (m_bMemDC){ // Create a Memory DC CreateCompatibleDC(pDC); pDC->GetClipBox(&m_rect); m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height()); m_oldBitmap = SelectObject(&m_bitmap); SetWindowOrg(m_rect.left, m_rect.top); } else { // Make a copy of the relevent parts of the current DC for printing m_bPrinting = pDC->m_bPrinting; m_hDC = pDC->m_hDC; m_hAttribDC = pDC->m_hAttribDC; } }
~CMemDC() { if (m_bMemDC) { // Copy the offscreen bitmap onto the screen. m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), this, m_rect.left, m_rect.top, SRCCOPY); //Swap back the original bitmap. SelectObject(m_oldBitmap); } else { // All we need to do is replace the DC with an illegal value, // this keeps us from accidently deleting the handles associated with // the CDC that was passed to the constructor. m_hDC = m_hAttribDC = NULL; } }
// Allow usage as a pointer CMemDC* operator->() {return this;}
// Allow usage as a pointer operator CMemDC*() {return this;} };
#endif
내용 구현 :
Flicker Free Code 사용한 클래스 의 이름을 CMemDC 라고 하겠습니다. 해당 코드는 위에 있습니다.
우선 CMemDC로 선언한 변수에 현재 화면에 그려진 DC를 적용시켜 줍니다. m_pTestFormDlg->m_pParentMemDC = new CMemDC(pDC, &rect);
해당 pDC와 화면 영역 값을 넘겨 주면서 생성해 줍니다. 원래 이 부분의 rect는 제가 집어 넣은 겁니다. 안해주면 내부에서 GetClipRect()로 값을 구해서 적용하게 되어 있습니다.
DC와 같이 적용된 CMemDC 쪽에 BitBlt를 사용해서 해당 DC의 내용을 그립니다. m_pTestFormDlg->m_pParentMemDC->BitBlt( 0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
이제 이 DC를 다른 곳에서 BitBlt를 해서 사용하시면 됩니다. pdc->BitBlt(0, 0, 850, 666, m_pParentMemDC, 0, 0, SRCCOPY);