Program Language/API | MFC

[MFC] Control 깜빡임 방지 코드

야곰야곰+책벌레 2021. 4. 22. 11:36
728x90
반응형

MFC에서 Control을 Update 하다 보면 깜빡임이 발생한다. 

그럴 경우에 Update를 하고자 하는 기능 사이에 다음 함수를 추가하면 깜빡임을 해결할 수 있다.

 

LockWindowUpdate();  - Control Update 중지
UnlockWindowUpdate(); - Contorl Update 중지 해제

 

아래와 같이 대량의 업데이트가 필요할 경우 깜빡임을 제거할 수 있다.

	LockWindowUpdate();
    
	for (unsigned int row = 0; row < mcData.size(); row++)
	{
		InsertItem(row, CString(mcData[row].machID), 0);
		SetItemText(row, 1, CString(mcData[row].submachID));
		SetItemText(row, 2, CString(mcData[row].machcompID));
		SetItemText(row, 3, CString(mcData[row].machsubcompID));
		SetItemText(row, 4, CString(mcData[row].name));
	}
    
	UnlockWindowUpdate();

 

  상기와 같이 특수한 상황이 아니라면 Window의 WM_PAINT 메시지의 호출에 대해서 검토해 보자. WM_PAINT는 아래와 같은 상황에서 호출된다.

  • 윈도우가 처음 만들어졌을 때
  • 윈도우가 이동하였을 때
  • 윈도우의 크기가 바뀌었을 때
  • 윈도우가 가졌다가 나타났을 때
  • 스크롤 동작을 할 때
  • 유저가 호출했을 때 (UpdateWindow(), RedrawWindow(), InvalidatedRect(), InvalidRgn() 등의 호출)

그런데 WM_PAINT가 호출되기 전에 대부분 함께 호출되는 메시지가 있는데 그것은 WM_ERASEBKGND이다. 배경을 지운다는 메시지이다. 윈도우에서 깜빡임은 대부분 여기서 발생한다.

  1. WM_ERASEBKGND 받음
  2. 배경 지움
  3. WM_PAINT 받음
  4. 그림

배경을 지우는 행위가 '깜'이라면 다시 그리는 행위는 '빡'이다. 그래서 가장 쉬운 방법으로는 WM_ERASEBKGND 메시지를 처리하여 배경 지우는 행위를 막는 것이다.

BOOL CMxButton::OnEraseBkgnd(CDC* pDC)
{
	return FALSE; // OnEraseBkgnd가 호출되지 전에 FALSE로 반환해버린다.

	return CMFCButton::OnEraseBkgnd(pDC);
}

그런데 이것으로 해결되지 않는 경우가 있는데, 이것은 Child로 종속된 경우, 부모 창에서 자식 창에 가려진 부분을 다시 그리면서 또 다른 깜빡임이 발생한다. 이 때는 부모 창에 WS_CLIPCHILDREN 스타일을 추가하여 자식 창에 가려지는 부분은 다시 그리기를 하지 않도록 만들자.

	ModifyStyleEx(NULL, WS_CLIPCHILDREN);

CMFCPropertyGridPropert 같은 경우에는 부모 창에서 WS_CLIPCHILEREN을 설정하면 런타임 에러가 발생하기도 한다. 상황을 잘 파악하여 오류가 없는 방법을 사용하도록 하자.

728x90
반응형