Windows/Windows API
WM_SIZE
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 메시지는 윈도우 크기에 상관없이 일정한 레이아웃을 유지하기 위해 빈번하게 사용된다.