Win32_API - WM_PAINT 재호출(InvalidateRect,UpdateWindow)

컴퓨터/Win32-API

728x90
반응형

서론

Windows 프로그래밍을 하다 보면, 그래픽에 의존하는 프로그램이 대부분입니다. 따라서 WM_PAINT를 원하는 시점에서 호출하여서 다시 그래픽 설정을 할 필요성이 많이 있습니다. 

본문에서는 WM_PAINT를 사용자가 원하는 시점에 호출하기 위한 방법에 대해 알아보겠습니다.

 

WM_PAINT는 언제 생기는가?

WM_PAINT는 그리기 무효화 영역이 발생한 후 발생됩니다. 

간단한 예를 들자면 모니터에 보이지 않는 그래픽을 처리하고 있기에는 컴퓨터의 입장에서 불필요한 일입니다. 따라서 모니터에서 보이지 않는 순간, 무효화 영역이 발생이 되고 이 무효화된 영역이 다시 모니터에 활성화되는 순간 WM_PAINT 메시지가 생기게 됩니다. 

자세한 내용은 아래 링크를 참조하세요.

 

 

Win32_API - WM_PAINT(창 그리기)

서론 윈도 응용 프로그래밍은 메시지 루프에 진입하여 운영체제의 명령어를 하나씩 처리하는 방식으로 프로그래밍됩니다. 본문에서는 가장 대표적이며, 어떻게 보면 필수적인 WM_PAINT 메시지에

blog-of-gon.tistory.com

위의 내용을 반대로 생각하면, 프로그램을 개발하던 도중 어떠한 시점에 WM_PAINT 메시지를 통해 그리기가 필요하다고 하는 경우 무효화 영역을 강제적으로 발생하면 될 것입니다. 이런 한 개념으로 접근하여 사용자가 원하는 시점에 WM_PAINT 메시지를 발생시켜 보도록 합시다.

 

무효화 영역을 생성시키는 함수 - InvalidateRect()

이 함수는 강제적으로 특정 영역을 무효화시키는 함수입니다.

함수의 원형을 살펴보도록 합시다.

BOOL
InvalidateRect(
    HWND hWnd,
    CONST RECT *lpRect,
    BOOL bErase);
  • hWnd - 무효화시킬 윈도 핸들 값
  • *lpRect - 무효화시킬 영역
  • bErase
    • TRUE - 배경까지 무효화
    • FALSE - 배경을 제외한 무효화

위 인자들을 통해서 무효화 영역을 강제로 생성합니다. 

모니터에 프로그램의 화면이 보인다면 무효화 영역이 존재하기 때문에 WM_PAINT 메시지가 발생하게 됩니다.

만약 원하는 시점에서 전체 부분을 무효화시키고 싶다면 다음과 같이 함수를 호출하면 됩니다.

InvalidateRect(hWnd, NULL, TRUE);

2번째 인자에 NULL은 특정 범위가 아닌 해당 윈도의 전체 영역을 선택하고 싶을 때 사용합니다.

 

InvalidateRect함수를 호출하여 무효화 영역을 사용자에 의도에 따라 설정해 주어 WM_PAINT 메시지를 발생시킬 수 있습니다.

 

WM_PAINT 메시지는 바로 처리되지 않는다. 

여러분들이 간단한 Windows 프로그래밍을 하다 보면 InvalidateRect함수만 호출하여도 원하는 결과를 얻을 수 있습니다.

하지만 여기에서 하나의 문제점이 발생하게 됩니다. 

바로 콜백 함수에서 메시지의 처리는 큐 자료구조의 형태로 먼저 생성된 메시지부터 순차적으로 처리하게 되어있습니다.

 

정리하자면, WM_PAINT 메시지가 발생하기 전 메시지들을 처리한 후 WM_PAINT메시지를 처리할 수 있습니다.

이 말은 복잡하고 크기가 큰 프로그램일수록, 많은 메시지들을 처리해야 하는 프로그램일수록 원하는 시점에서 InvalidateRect함수를 호출하여도 WM_PAINT 메시지를 처리하기까지의 시간이 많이 걸린다는 것을 의미합니다.

즉, 원하는 시점보다 늦어지는 현상이 생길 수 있습니다.

따라서 이를 극복하기 위해 UpdateWindow함수가 필요합니다.

 

UpdateWindow 함수 

이 함수를 통해 메세지 큐에서 순자적으로 WM_PAINT를 기다리지 않고, WM_PAINT 메시지를 먼저 처리할 수 있게 해주는 함수입니다. 

보통 무효화 영역을 지정하는 시점에서 다시 WM_PAINT 메시지의 동작을 원하기 때문에, InvalidateRect와 UpdateWindow함수는 하나의 세트처럼 사용되기도 합니다.

 

InvalidateRect(hWnd, NULL, TRUE); // 무효화 영역 생성하기 위한 함수
UpdateWindow(hWnd); // WM_PAINT를 우선적으로 처리하기 위한 함수

 

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

91년생 공학엔지니어의 개발일지

TODAY :

YESTER DAY :

TOTAL :