JHB의 프로그래밍 삽질기

MFC에서 Draw 사용시 주의할 점들 본문

PROGRAMMING/C C++ MFC

MFC에서 Draw 사용시 주의할 점들

roter 2010.08.24 11:15



1. 더블 버퍼링에 대하여

더블버퍼링은 WM_PAINT에서 해주는 일을 간략화 시켜주기 위해! 다른 곳에서 미리 BITMAP에다가 다 그려놓고 WM_PAINT에서는 해당 BITMAP을 불러와주는 일만 해주도록 하는 것. MFC의 경우엔 CBitmap을 사용한다
클래스 내에 CBitmap m_BitmapBG; 뭐 이런식으로 하나 만들고
다른 함수 (예를 들어 고정 배경이라면 Init부분에서)에서 MemDC를 만들어 SelectObject로 m_BitmapBG를 선택한 후 그리기를 완료한다. 이 때 중요한 점은 CBitmap.DeleteObject()를 하면 안된다는 것! 이건 WM_DESTROY시에 해줘야 한다.
여튼.. m_BitmapBG에 그리기를 완료하고나서는 WM_PAINT에서는 m_BitmapBG만 Select하고 BitBlt으로 불러와 주면 된다.
예제를 보면..

 CDC* pdc;
 CDC* p_MemDc = new CDC();
 pdc = GetDC();

 m_BitmapBG.CreateCompatibleBitmap(pdc,x,y); //비트맵 크기를 꼭 할당해야한다.
 p_MemDC->CreateCompatibleDC(pdc); //MemDC도 크기를 꼭 할당해야한다.
 p_MemDC->SelectObject(&m_BitmapBG); //MemDC의 Bitmap으로 m_BitmapBG를 선택한다.

이후에는 p_MemDC에 그리기 작업을 다 수행해준다.
GetDC로 얻은 것은 ReleaseDC(pdc);로 지워주고
절대 ->DeleteDC 이딴건 쓰지 말 것.


이제 WM_PAINT를 보면
 CPaintDC dc(this);
 
 CDC *p_MemDC = new CDC();
 CBitmap* p_oldBitmap;

 p_MemDC->CreateCompatibleDC(&dc);
 p_oldBitmap = p_MemDC->SelectObject(&m_BitmapBG);

 dc.BitBlt(0,0,x,y,p_MemDC,0,0,SRCCOPY);

 p_MemDC->SelectObject(p_oldBitmap);
 delete p_MemDC;

소스가 이게 전부이다. MemDC를 하나 생성해 SelectObject로 아까 그려준 비트맵을 선택하여 BitBlt으로 PaintDC에 고속 복사 해준다. 끝~


2. delete에 관하여

우선, 포인터 변수 중 new로 생성한 녀석은 반드시 delete가 있어야 한다. 한마디로 하나의 new에는 하나의 delete가 필히 존재해야 한다.
Object들 역시 사용을 완료한 녀석들은 DeleteObject();로 지워준다. DeleteObject();로 지워주기 전에 DC의 Object는 OldObject로 교체해 주는 센스..
DC도 사용 후에는 반드시 DeleteDC를 해주자.
단, new를 사용하지 않고 걍 포인터를 사용하여 지역변수로 생성한 녀석들은 굳이 delete해주지 않아도 된다.

예를 보면

  CDC* pdc;
  CPen pen(PS_SOLID,1,RGB(255,255,255)), *p_oldpen;
  pdc = GetDC();
  p_oldpen = p_MemDC->SelectObject(&pen);

  p_MemDC->MoveTo(0,0);
  p_MemDC->LineTo(50,50);

  p_MemDC->SelectObject(p_oldpen);
  pen.DeleteObject();
  ReleaseDC(pdc);

이렇게 된다.
만약 생성을 CPen* pen = new CPen(); 이런식으로 했다면 다 사용한 후
delete pen; 을 꼭 해줘야 한다.


p.s> CPaintDC는 delete를 안해주는데.. 왜 안해주는지 모르겠다. 걍 MFC하지 말래서 안한다 =_=aa

0 Comments
댓글쓰기 폼