본문 바로가기

공부/MFC

Visual C++ 2008 MFC Chapter 18 깜박임 방지

이번 챕터에 있는 더블버퍼링 을 공부하기 위한 챕터 18 공부.

응용 프로그램에서 화면의 크기를 조정할 때 대부분 화면 상 깜박임이 발생한다.

메인 프레임 윈도우 일부가 그러는 것은 어쩔 수 없다고 하더라도. 클라이언트 뷰 윈도우가 통째로 깜빡이면

그리 좋은 모습은 아니라 개선을 해야하는 필수 대상이라고 한다. 뭐 본적은 없지만 .

WM_ERASEBKGND 메시지에 대하여 알아야 한다.

--------- 화면 그리기의 구조 -------

이 메시지는. WM_PAINT 메시지와 더불어 윈도우를 다시 그릴 때 발생하는 메시지 중 하나이다. 윈도우가 클라이언트 영역과 비 클라이언트 영역으로 구별되어 있고, 각각을 그리도록 하는 메시지 는
WM_PAINT 와 WM_ERASEBKGND  이다. 그러나 클라이언트 영역에서는 WM_PAINT 메시지보다 WM_ERASEBKGND 메시지가 먼저 발생한다.

그리고 이 WM_ERASEBKGND 는 윈도우의 배경을 그리는 코드를 실행하며. 일반적으로 윈도우의 배경이 흰색이므로

흰색으로 배경을 칠하게 되는 것이다.[이 때에 깜박임이 발생한다]

따라서 배경을 그리는 작업이 불필요하다고 생각되면 WM_ERASEBKGND  메시지 핸들러 함수를 등록한 후 상위 클래스의 멤버를 호출하지 않고 반환하도록 코드를 아래와 같이  수정하면 깜박임이 줄어들게 된다.[많이 티가 나게 줄어드는것은 아니다.]

=======================================================
BOOL CRedrawDemoView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
// return CView::OnEraseBkgnd(pDC);
}

=====================================================

RedrawWindow의 원형보기
///////////////////////////////////////////////////////////////


예제코드 출력화면


파일 업로드.






------------ 눈속임의 미학 ------------

배경이 투명한 

윈도우의 구현.


// CTransparentDemoView 메시지 처리기

BOOL CTransparentDemoView::OnEraseBkgnd(CDC* pDC)
{
CRect Rect;
GetClientRect(&Rect);
pDC->FillSolidRect(&Rect, RGB(255, 255, 255));

CImage ImageBackground;
ImageBackground.LoadFromResource(AfxGetInstanceHandle(), IDB_Background);
ImageBackground.BitBlt(pDC->m_hDC, 0, 0);

return TRUE;
// return CView::OnEraseBkgnd(pDC);
}

이 코드의 핵심은 OnEraseBkgnd () 메시지 핸들러 함수의 인자로 전달받은
DC에 이미지를 로드하여 출력하는 코드이다. 이 이미지는 자식 윈도우와 함께 사용할
이미지가 된다.

다음 코드는 클라이언트 뷰 윈도우의 자식 윈도우인 CTranspartentWnd 클래스의
OnEraseBkgnd()함수이다.
 

BOOL CTransparentWnd::OnEraseBkgnd(CDC* pDC) { CRect Rect, ParentRect;//여기부터 GetClientRect(&Rect); GetParent()->GetClientRect(&ParentRect);// 자식 윈도우의 왼쪽 위가 부모 윈도우 기준으로 어디인지 계산하는 코드 CPoint ptLeftTop = CPoint(0, 0); ClientToScreen(&ptLeftTop); GetParent()->ScreenToClient(&ptLeftTop); CDC MemDC;//여기부터 CBitmap Bmp; MemDC.CreateCompatibleDC(NULL); Bmp.CreateBitmap(ParentRect.Width(), ParentRect.Height(), MemDC.GetDeviceCaps(PLANES), MemDC.GetDeviceCaps(BITSPIXEL), NULL); CBitmap* pOldBmp = MemDC.SelectObject(&Bmp);//메모리 DC에 적절한 CBitmap 클래스 객체를 생성하여 선택하는 코드 GetParent()->SendMessage(WM_ERASEBKGND, (WPARAM)MemDC.m_hDC);// 부모 윈도우에 WM_ERASEBKGND 메시지를 보냄 pDC->BitBlt(0, 0, Rect.Width(), Rect.Height(), &MemDC, ptLeftTop.x, ptLeftTop.y, SRCCOPY);//화면 출력. MemDC.SelectObject(pOldBmp); return TRUE; // return CWnd::OnEraseBkgnd(pDC); }

위의 코드대로 입력된 출력화면은 다음과 같다.



이런 식으로 자식 윈도우가 출력되면서 앞에서 부모 윈도우의 출력을 가리게 된다.

이 코드에서 리턴 트루 위쪽의 코드를 모두 주석화 하면.

아래와 같이 가리는 출력이 아닌 겹치는 출력이 된다.



파일 업로드



팁 : 해당 코드를 찾고싶을때는 클래스 뷰 를 사용해서 해당 함수를 찾는것이 빠르다.

'공부 > MFC' 카테고리의 다른 글

대화상자 로 경로 찾기  (0) 2011.12.21
MFC 더블 버퍼링 [ Double Buffering ]  (6) 2011.12.14
그림판 만들기 주석첨부 따라하기 클리어  (0) 2011.12.12
그림판 따라하기 진행중  (0) 2011.12.12
커서 제작. 핫 스폿  (0) 2011.12.09