|
윈도우 같은 GUI 운영체제에서 위 그림과 같이 창들이 서로 겹치는 것은 매우 당연한 기능 중 하나이다. 그러나 최초의 윈도우 1.0에서는 이런 기능이 지원되지 않았다. 버전 2.0부터 이렇게 윈도우들이 서로 겹치는, 즉 overlapped 될 수 있었다. Win32 API를 사용한 분들은 WS_OVERLAPPED (WS는 Window Style의 약자)라는 #define을 본 적이 있을 것이다. 이렇게 창들이 오버랩 되는 것이 하나의 특별한 기능으로 간주되던 시절이 있었다. 이 겹쳐지는 윈도우들의 구현 중 핵심은 가려진 부분을 다시 그릴 수 있는 메카니즘일 것이다. 위 그림처럼 노트패드 위에 탐색기가 있고 탐색기를 다른 곳으로 보내면, 노트패드의 가려졌던 부분은 어떤 방식으로도 다시 그려져야만 한다. 이 기능을 구현하기 위해서는 크게:
이 정도의 방법이 있다. 보다시피 메모리를 써가며 빠르게 복원을 시킬 것인가, 아니면 메모리를 아끼지만 복원에는 다소 시간이 걸리는 것이냐의 전형적인 시간과 공간의 tradeoff인 것이다. 윈도우의 경우에는 이 두 가지 방법 모두를 사용한다. 방법 1은 바로 마우스 커서가 윈도우 창들을 움직일 때 사용한다. 마우스 커서가 차지하는 부분은 많아봐야 32x32 픽셀이므로 메모리에 화면 내용을 저장해도 부담이 되지 않는다. 그러나 일반적인 창들의 복원은 방법 2을 이용한다. 가려진 부분을 새로 그리라는 메세지를 운영체제가 해당 어플리케이션에게 보냄으로써 구현이 된다. 즉, 화면 내용을 별도의 메모리에 기억하지 않는다. 그러기에는 너무 많은 메모리가 필요하다. 그래서 윈도우 프로그래밍 공부하신 분들이라면 너무나 잘 아는 WM_PAINT 메세지를 이용하여 이것을 구현한다. (WM_은 Windows Message의 약자이다)
위 그림에서 탐색기를 최소화 시킨다고 하자. 그러면 노트패드의 가려졌던 부분은 다시 복원이 되어야한다. 이 때, 윈도우 운영체제는 이 복원이 되어야하는 영역을 무효화한다. 그리고 이 무효화한 영역을 최소한으로 감싸는 사각형 정보 (위 그림에서는 10, 40부터 400, 300까지) 를 WM_PAINT 메세지와 함께 노트패드에게 보낸다. 그러면 노트패드의 WM_PAINT 메세지를 처리하는 함수는 이것을 받아 적절히 해결해야 한다. 이것이 전통적인 윈도우 운영체제의 겹쳐지는 창들을 구현하기 위한 일반적인 방법이다. (사실 윈도우 프로그램의 본질은 매우 간단한데, 윈도우 운영체제가 보내는 각종 윈도우 메세지 WM_*에 대응되는 콜백함수, 즉 Windows Procedure를 제공하는 것이다.) WM_PAINT는 이 경우 뿐만 아니라 최초로 윈도우가 그려질 때, 창 크기가 변화될 때 등 매우 수시로 불려지는 메세지다. 1초에도 수십번이 불릴 수 있다. 그래서 이 메세지는 최적화에 늘 신경을 써야한다. 이 부분을 그냥 대충 짜면 창 크기를 변화 시킬 때 마다 깜빡인다거나 CPU를 엄청나게 먹는 불상사가 발생한다. 과거 이런 프로그램들을 적지 않게 보았을 것이다. 단순히 다른 윈도우가 특정 프로그램 위를 움직이게 하는 것만으로도 그 프로그램의 전체 화면이 껌뻑이며 새로 그려지는 것을 본 적이 있을 것이다. 무효화된 영역을 특별히 고려해서 그 부분만 그려도 되는데 그냥 귀찮아서 모든 화면이 새롭게 그렸기 때문이다. (사실 껌뻑임의 가장 큰 이유는 WM_PAINT 이전에 화면을 지우라는 WM_ERASEBKGND라는 메세지를 제대로 처리하지 않아 발생하는 것이기는 하다.)
그러나 이제는 메모리가 가장 싼 컴퓨터 자원이 되고 말았다. 주기억장치뿐만 아니라 그래픽 카드의 메모리도 엄청나게 발전하였다. 2001년만 하더라도 비디오램은 고작 4~32MB 수준이었지만 이제는 128MB, 256MB도 그렇게 비싸지가 않다. 2008년 1월 13일 다나와 기준. 1GB 메모리가 이제 2만원도 하지 않는다. 256MB짜리 그래픽 카드도 단 돈 10만원. 비스타에서 도입된 Aero 기능, 보다 프로그래머틱하게 말하면 Desktop Windows Management에서는 이런 저렴해진 메모리를 적극적으로 활용한다. 창의 내용을 복원할 때도 이제 그래픽 카드의 메모리에다 몽땅 올려다 놓는다. 그래서 각 창들의 화면을 그 다음에 합성을 하여 여러 3차원 효과 등을 구현할 수 있다. 그렇다면 WM_PAINT 메세지는? 위에서 예로 든 노트패드와 탐색기 예에서 더 이상 탐색기가 치워져도 노트패드에 WM_PAINT 메세지가 불려지지 않는다. 직접 간단히 프로그램을 만들어놓고 테스트를 해보니 단순히 창을 최소화 및 복원, 그리고 다른 창에 의해 가려졌다가 다시 보여질 때는 힘들게 다시 그리지 않고 그대로 메모리의 내용을 가지고 복원을 한다. 따라서 과거 아무 생각없이 프로그램을 짜서 껌뻑이던 프로그램도 비스타에서는 잘 작동할 수 있게 되었다. 물론, 비스타에서도 Aero 기능을 끄고 (즉, dwm.exe가 사라지면) 테스트를 해보면 과거 XP 시절과 같이 끊임없이 WM_PAINT 메세지가 발생한다. 나는 꼼꼼한 윈도우 프로그래머를 가늠하는 기준 중 하나가 창이 복원되거나 크기가 변경될 때 그 프로그램이 얼마나 잘 반응하는가였다. 얼마나 WM_PAINT 메세지 핸들러를 잘 만들었냐를 보는 것이었다. 그러나 메모리 가격이 엄청나게 저렴해지고 운영체제도 발전함에 따라 이런 기준은 이제 무의미하게 되었다.
@ WM_PAINT 메세지 뿐만 아니라 다른 메세지 처리도 잘 해야만한다. 만약 특정 시간 동안 (보통 5초) 메세지 처리를 마치지 못하면 흔히 보는 "응답 없음"이라는 상태로 창 상태가 바뀌게 된다. @ 비스타에서 프로그램을 좀 만들다가 WM_PAINT 메세지가 발생하지 않음을 보고 신기해서 적어본 글. 역시 프로그래머가 실력있고 없음은 척박한 환경과 자원에서도 잘 돌아가는 프로그램을 짜는 능력인가?
최근 등록된 덧글
개발자 입장에서의 수많은 ..
by Jiyoon at 02/04 저도 아들 돌잔치때 돌잡이 .. by 박상욱 at 01/18 미국 대학원 원서 작성중에 p.. by 태클사이야 at 01/13 TO: 박PD 로그인 하지 않아.. by 박응용 at 01/10 http://gigglehd.com/zbx.. by dhunter at 12/28 우와.. 좋네요. 태반이 .. by 윤광배 at 12/17 항상 좋은 글 잘 보고 있습니.. by y2k at 11/23 글이 좋아서 제 블로그에 담.. by 쏭섭 at 11/23 최근 등록된 트랙백
메뉴릿
이글루 파인더
|