창 그리기
창이 만들어졌습니다. 이제 창 안에 무언가를 표시하려고 합니다. Windows 용어로 이는 창 그리기라고 합니다. 비유하자면 창은 채워지기를 기다리는 빈 캔버스입니다.
때때로 프로그램은 창의 모양을 업데이트하기 위해 그리기를 시작합니다. 운영 체제에서 창의 일부를 다시 그려야 한다는 알림이 표시되는 경우도 있습니다. 이 경우 운영 체제는 창에 WM_PAINT 메시지를 보냅니다. 그려야 하는 창 부분을 업데이트 영역이라고 합니다.
창이 처음 표시되면 창의 전체 클라이언트 영역을 그려야 합니다. 따라서 창을 표시할 때 항상 하나 이상의 WM_PAINT 메시지가 표시됩니다.
사용자는 클라이언트 영역의 그리기만 담당합니다. 제목 표시줄을 포함한 주변 프레임은 운영 체제에 의해 자동으로 그려집니다. 클라이언트 영역 그리기를 완료한 후 업데이트 영역을 지우면 변경 내용이 발생할 때까지 다른 WM_PAINT 메시지를 보낼 필요가 없다고 운영 체제에 알립니다.
이제 사용자가 창의 일부를 가리도록 다른 창을 이동한다고 가정합니다. 가려진 부분이 다시 표시되면 해당 부분이 업데이트 영역에 추가되고 창에 또 다른 WM_PAINT 메시지가 수신됩니다.
사용자가 창을 늘리면 업데이트 영역도 변경됩니다. 다음 다이어그램에서 사용자는 창을 오른쪽으로 늘립니다. 창의 오른쪽에 새로 노출된 영역이 업데이트 영역에 추가됩니다.
첫 번째 예제 프로그램에서 그리기 루틴은 매우 간단합니다. 전체 클라이언트 영역을 단색으로 채우기만 합니다. 하지만 이 예제는 몇 가지 중요한 개념을 보여 주는 데 충분합니다.
switch (uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// All painting occurs here, between BeginPaint and EndPaint.
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(hwnd, &ps);
}
return 0;
}
BeginPaint 함수를 호출하여 그리기 작업을 시작합니다. 이 함수는 다시 그리기 요청에 대한 정보로 PAINTSTRUCT 구조체를 채웁니다. 현재 업데이트 영역은 PAINTSTRUCT의 rcPaint 멤버에 제공됩니다. 이 업데이트 영역은 클라이언트 영역을 기준으로 정의됩니다.
그리기 코드에는 두 가지 기본 옵션이 있습니다.
- 업데이트 영역의 크기에 관계없이 전체 클라이언트 영역을 그립니다. 업데이트 지역 밖에 있는 모든 항목이 잘립니다. 즉, 운영 체제는 이를 무시합니다.
- 업데이트 영역 안 창의 일부만 그려서 최적화합니다.
항상 전체 클라이언트 영역을 그리면 코드가 더 간단합니다. 그러나 그리기 논리가 복잡한 경우 업데이트 영역 외부의 영역을 건너뛰는 것이 더 효율적일 수 있습니다.
다음 코드 줄은 시스템 정의 창 배경색(COLOR_WINDOW)을 사용하여 업데이트 영역을 단일 색으로 채웁니다. COLOR_WINDOW가 나타내는 실제 색상은 사용자의 현재 색 구성표에 따라 달라집니다.
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
FillRect의 세부 정보는 이 예제에서 중요하지 않지만 두 번째 매개 변수는 채울 직사각형의 좌표를 제공합니다. 이 경우 전체 업데이트 영역(PAINTSTRUCT의 rcPaint 멤버)을 전달합니다. 첫 번째 WM_PAINT 메시지에서 전체 클라이언트 영역을 칠해야 하므로 rcPaint는 전체 클라이언트 영역을 포함합니다. 후속 WM_PAINT 메시지에서 rcPaint는 더 작은 직사각형을 포함할 수 있습니다.
FillRect 함수는 오랫동안 Windows 그래픽을 지원해 온 GDI(그래픽 디바이스 인터페이스)의 일부입니다. Windows 7에서 Microsoft는 하드웨어 가속과 같은 고성능 그래픽 작업을 지원하는 Direct2D라는 새로운 그래픽 엔진을 도입했습니다. Direct2D는 Windows Vista용 플랫폼 업데이트를 통해 Windows Vista용으로, Windows Server 2008용 플랫폼 업데이트를 통해 Windows Server 2008용으로도 사용할 수 있습니다. (GDI는 여전히 완전히 지원됩니다.)
그리기를 완료한 후 EndPaint 함수를 호출합니다. 이 함수는 업데이트 영역을 지웁니다. 이 영역은 창이 그리기를 완료했음을 Windows에 알립니다.