aucd29 2013. 10. 1. 18:51

앞에서 만든 예제는 과연 작업 영역 중앙에 문자열을 출력하기는 하였다. 윈도우가 만들어질 때 작업 영역 좌표를 구해 놓고 그릴 때 이 좌표를 기준으로 중앙 좌표를 계산하기 때문이다. 그런데 일단 출력된 윈도우의 크기를 변경하면 작업 영역의 크기가 달라져 더 이상 문자열은 작업 영역의 중앙에 있지 않게 된다.

문자열을 계속 작업 영역 중앙에 두고 싶으면 윈도우의 크기가 변경될 때마다 다시 출력해 주어야 하는데 이때 사용되는 메시지가 WM_SIZE 메시지이다. 이 메시지는 윈도우의 크기가 변경되었을 때 보내진다. 이때 lParam의 하위 워드에는 변경된 후의 윈도우 폭이, 상위 워드에서는 높이가 전달되며 wParam에는 이 메시지가 발생한 이유를 나타내는 플레그가 전달된다.

플레그
SIZE_MAXHIDE 다른 윈도우가 최대화되어 이 윈도우가 가려졌다.
SIZE_MAXIMIZED 최대화되었다.
SIZE_MAXSHOW 다른 윈도우가 원래 크기로 복구되어 이 윈도우가 드러났다.
SIZE_MINIMIZED 최소화되었다.
SIZE_RESTORED 크기가 변경되었다.

일반적으로 이 플레그는 잘 사용되지 않는다. WM_SIZE 메시지를 사용하여 윈도우 크기가 변경될 때마다 문자열 위치를 수정하도록 WndProc을 다음과 같이 수정해 보자.

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	static RECT rt;
	switch(iMessage) {
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		SetTextAlign(hdc,TA_CENTER);
		TextOut(hdc,rt.right/2, rt.bottom/2, "Center String",13);
		EndPaint(hWnd, &ps);
		return 0;
	case WM_SIZE:
		GetClientRect(hWnd, &rt);
		InvalidateRect(hWnd, NULL, TRUE);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

WM_CREATE 대신 WM_SIZE에서 윈도우 크기가 변경될 때마다 작업 영역의 크기를 다시 계산하고 화면을 다시 그리므로 문자열은 윈도우의 크기에 상관없이 항상 같은 위치에 있게 된다. WM_SIZE에서 GetClientRect 함수를 호출하여 작업 영역의 크기를 다시 조사하는데 lParam으로도 작업 영역 크기가 전달되므로 다음과 같이 쓸 수도 있다.

case WM_SIZE:
	rt.right=LOWORD(lParam);
	rt.bottom=HIWORD(lParam);
	InvalidateRect(hWnd, NULL, TRUE);
	return 0;

WM_SIZE 메시지는 윈도우 크기에 상관없이 일정한 레이아웃을 유지하기 위해 빈번하게 사용된다.