개발하는 리프터 꽃게맨입니다.

[WinAPI] hWnd 윈도우 핸들, hDC 본문

Window API

[WinAPI] hWnd 윈도우 핸들, hDC

파워꽃게맨 2024. 1. 31. 15:03

 

hWnd 

핸들 윈도우란 뭔가?

 

윈도우의 핸들은 운영체제의 커널 오브젝트를 사용하기 위해 필요한 장치라고 볼 수 있습니다.

우리가 프로그램으로 만든 윈도우는 고유 식별 id가 있습니다.

이런 고유 식별 id를 HWND로 관리하고 있다고 보시면 됩니다.

 

객체가 메모리단에 잡히긴 했는데 우리가 함부로 접근할 수 없습니다.

윈도우는 운영체제가 관리하는 객체이기 때문이죠.

그래서 우리는 hwnd라는 id를 통해서 윈도우를 간접적으로 다뤄야만 하는 것입니다.

 

윈도우에서 동작하는 프로그램을 만들기 위해서는 무조건 hwnd를 다뤄야만 합니다.

화면에 그림을 그리는 것 또한 hwnd에 접근해서 그려줘야만 하죠

 

 

이런 식으로 말이죠.

 

추가적으로 윈도우 프로그래밍을 할 때는 이 H 자료형 시리즈가 중요합니다.

 

HPEN HDC HBRUSH 등등 많습니다.

 

이것들의 정의를 까보면

다들 정수형 id를 들고있고

얘네들도 결국엔 커널 오브젝트를 다루기 위한 id 값이라는 식별자르 가지고 있다고 생각하시면 됩니다.

근데 이 id는 hwnd를 기반으로 얻어줘야 하는 것이죠.

 

저 위 사진의 

BeginPaint 는 hwnd를 인자로 받고 있습니다.

즉, hwnd 의 아이디를 전달해서

hwnd의 ID를 통해 HDC를 만들고

HDC에 직접적으로 명령을 내려서

Textout 즉, 해당 식별자 ID의 윈도우창에 텍스트를 그려라~

라고 명령해주는 것입니다.

(참고로 이 때 잘못된 ID를 전달해주면 제대로 그려지지 않습니다.) 

 


 

HDC (Handle Device Context) 에 대해서도 알아보도록 하죠

hdc는 렌더링과 관련된 동작을 할 때 필요한 많은 커널 오브젝트를 다룰 수 있도록 해줍니다.

그래서 우리는 윈도우에 그림을 그리기 위해서는

hdc를 이용해서 그림을 그려야만 합니다.

 

 

hdc가 그릴 윈도우는 hwnd

hdc 기본 펜은 Black (외곽선)

hdc 기본 브러쉬는 White (채우기)

입니다.

 

예를들어서 여러가지 도형을 그린다고 해봅시다.

 

그러면 이런식으로 적절한 함수를 호출해서

hdc를 인자로 넘겨서

hdc에 그려주면 됩니다.

재밌죠?

hdc는 그림을 그릴 수 있는 도화지라고 생각하시면 됩니다.

 

 

이런 식으로 펜 색상과 채우기도 바꿀 수 있는데

관련된 여러가지 함수가 준비되어 있습니다. 

MSDN을 참고하는게 더 좋을 겁니다.

 

 

자 그러면 우리는 그림을 그릴 수 있는 도화지가 준비되었습니다.

그리고 이 카테고리의 이름은 게임 개발을 위한 Window API 입니다.

 

그러면 우리는 키입력에 따라서 도형을 그려주기만하면 게임을 만들 수 있을까요?

오른쪽 방향키를 누르면 계속해서 오른쪽에 사각형을 그리는 식으로 말이죠.

 

아마 쉽지 않을 겁니다.

 

 

일단 이렇게 key입력을 받는 case를 추가해봤습니다.

좌표를 바꾸고 좌표를 토대로 사각형이 그려지도록 말이죠

 

근데 그려지지 않습니다.

왜일까요?

 

기본적으로 WM_PAINT는 무효화 영역이 발생될 때, 호출됩니다.

그저 키를 눌렀다고 다시 그려지는 것이 아닙니다.

 

그럼 무효화 영역은 어떻게 발생시킬까요?

 

윈도우의 창을 조절하거나, 윈도우를 모니터 바깥으로 빼면 무효화 영역이 발생합니다.

그러면 그림을 다시그리죠.

 

즉, WM_PAINT 를 호출하려면 '무효화 영역'을 만들어야 한다는 것입니다.

 

 

그런데 InvalidateRect 라는 함수를 이용하면 무효화 영역을 강제로 호출할 수 있습니다.

그러면 제대로 그려지는지 한 번 볼까요?

 

음.. 잘 움직이긴 하는데

부드럽지 못한 느낌이 듭니다.

이건 윈도우 자체 WM_KEYDOWN 메시지의 처리 방식 때문이에요.

어쨌든 뭔가 엄청 뻑뻑하고 평소에 하던 게임 캐릭터의 움직임과는 많이 다르지 않나요?

 

우리가 업데이트가 느린 지뢰찾기, 카드 게임 등은 만들려면 이런 식으로 만들수야 있겠지만,

초당 30~60 번 업데이트 및 렌더링을 해야하는 기존 게임을 이런 윈도우 메시지 처리로 만들기란 어렵습니다.

에초에 메시지 큐에 들어오는 메시지가 없으면 while 루프가 돌아가지 않기 때문이죠.

근데 우리가 게임을 키고 아무것도 하지 않더라도 게임은 자기 알아서 돌아가지 않습니까?

 

다음 주제는 게임을 위한 윈도우 API 루프를 만들어보는 시간을 가져보겠습니다.