Post Lists

2019년 1월 8일 화요일

DirectX Tutorial Lesson 3: Creating a Window

http://www.directxtutorial.com/Lesson.aspx?lessonid=11-1-3

DirectX 11을 공부하기 위해 이 자료를 보고 있다. 공부하던거 이어서 번역하겠다.

======================================

Handling Windows Events and Messages
우리가 일단 우리의 window를 만들었다면, 우리는 그것이 상호작용할 수 있도록 윈도우를 계속 유지할 필요가 있다. 물론, 만약 우리가 우리의 프로그램이 끝나면, 그것은 그렇지 않을 것이다. 그러나, 그것이 그렇다고 가정하여, 우리는 윈도우가 만들어지고 파괴되는 flash를 볼 것이다. 우리가 WinMain()에 도달했을 때.

끝내는 대신에, 우리의 프로그램은, window creation을 완료하고, main loop라고 불리는 것에 들어간다. 우리가 이전에 말했듯이, 윈도우즈 프로그래밍은 이벤트 기반이다. 이것은 우리의 윈도우가 우리의 윈도우가 우리에게 go를 줄 때 어떤 것을 한다는 것을 의미한다. 그렇지 않다면, 우리는 기다린다.

윈도우즈가 우리에게 한 메세지를 넘겨줄 때, 몇 가지것이 즉시 발생한다. 그 메세지는 event queue에 위치해있다. 우리는 queue로부터 그 메세지를 가져오기 GetMessage() 함수를 사용하고, 우리는 어떤 메세지 포맷을 다루기 위해 TranslateMessage()를 사용하고, 우리는 DispatchMessage() 함수를 사용하여, WindowPRoc() 함수로 보낸다. 그러고나서 그것은 그 메세지의 결과로 무슨 코드가 실행되어질지를 고른다.

복잡한 경우에, 다음은 모든 것이 발생하는 그 순서를 보여주는 다이어 그램이다.

이벤트를 다루는 것은 우리의 프로그램의 다른 절반이다. 그것은 그 자체로 두 개의 부분으로 분리된다:

1. Main Loop
2. The WindowProc() function

그 main loop는 오직 GetMessage(), TranslateMessage() 그리고 DispatchMessage()로 구성된다. WindowProc() 함수는 오직 어떤 메세지들이 보내졌을 때에만 작동하는 코드로 구성된다. 그것은 놀랍게도 간단하다. 그것에 대해 이제 좀 더 알아보자.

1. The Main Loop
위의 다이어그램으로 부터 보여지듯이, 이 섹션은 오직 세 개의 함수로 구성된다. 각 함수는 실제로 꽤 간단하고, 우리는 그것에 너무 자세히 들어갈 필요가 없지만, 우리는 그것들을 간단히 다룰 것이다.

다음은 main loop에 요구되는 코드이다:

시간을 많이 쓰지 않고, 이러한 코드의 각 라인을 봐보자

MSG msg;
MSG는 single event message와 관련된 모든 데이터를 포함하는 구조체이다. 너는 보통 이 구조체 내요에 직접 접근할 필요가 없을 것이지만, 그런 경우에, 나는 그것이 무엇을 포함하는지를 살짝 보여줄 것이다.

HWND hwnd : 그 메세지를 받았던 window의 handle을 포함
UINT message : 보내진 message의 identifier를 포함한다.
WPARAM wParam : 메세지에 대한 부가적인 정보를 포함한다. 정확한 의미는 무슨 메세지가 보내졌는지에 따라 다르다.
LPARAM lParam : WPARAM과 동일하고, 간단히 좀 더 많은 정보를 포함한다.
DWORD time : 그 메세지가 event queue에서 어떤 정확한 시간에 보내졌는지를 포함한다.
POINT pt : 정확한 마우스 위치를 포함하는데, 스크린 좌표에서이고, 그 메세지가 보내질 때 이다.


while(GetMessage(&msg, NULL, 0, 0))

GetMessage()는 메세지 큐에서 어떤 메세지를 받아서 우리의 msg 구조체에 넣는 함수이다. 그것은 항상 TRUE를 반환하는데, 그 프로그램이 exit하려는 상황을 제외하고이다. 그 상황에서 그것은 FALSE를 반환한다. 그 방식으로, 우리의 while loop는 그 프로그램이 완전히 끝날 때에만 break된다.

GetMessage() 함수는 다뤄질 4개의 파라미터가 있찌만, 우리는 그것의 prototype을 처음에 다룰 것이다:

BOOL GetMessage(
LPMSG lpMsg : 이 파라미터는 message 구조체의 포인터이고, 우리가 다뤘던 것과 같다. 우리는 우리의 구조체의 주소를 여기다 넣는다.
HWND hWnd : 이것은 메세지가 들어올 윈도우에 대한 handle이다. 그러나, 너는 우리가 여기에 NULL을 넣은 것을 눈치챌지도 모른다. NULL은 우리의 윈도우 중 어떤 것에 대해 다음 메세지를 받는 것을 의미한다. 우리는 실제로 여기에 hWnd value를 넣을 수 있고, 그것은 어떠한 차이도 만들지 않을 것이다, 그러나 만약 우리가 많은 윈도우를 가진다면 그것은 차이가 있다. 이 파라미터에 나는 NULL를 넣는다.
UINT wMsgFilterMin, UINT wMsgFilterMax : 이 파라미터들은 메세지의 종류들을 제한하는데 사용될 수 있는데, messege queue를 retrieve off하기 위해서이다. 예를들어: WM_KEYFIRST를 wMsgFilterMin에 사용하고, WM_KEYLAST를 사용하는 것은 그 메세지 타입을 키보드 메세지로 제한한다. WM_KEYFIRST와 WM_KEYLAST는 첫 번째와 마지막 키보드 메세지의 정수값과 같다. 마찬가지로, WM_MOUSEFIRST와 WM_MOUSELAST는 메세지 유형을 마우스 메세지로 제한한다.

이러한 파라미터에 한 가지 특별한 경우가 있다. 만약 너가 각 값을 '0'으로 채운다면, 그러면 GetMessage()는 너가 어떤 메세지는 모으고 싶다는 것을 가정한다, 그것의 값이 무엇이든. 너는 우리의 프로그램에서 우리가 이것을 했다는 것을 알 것이다.
)

TranslateMessage, DispatchMessage 생략

2. The WindowProc() Function
우리가 main loop를 다뤘으니, 너가 계속해서 들은 이 WindowProc() 함수를 봐보자.

여기에 무슨일이 발생하는지에 대해 간단한 설명이 있다. GetMessage()는 message를 받고, 우리는 그것을 바꾸고, DispatchMessage()함수를 사용해서 그것을 보낸다.

DispatchMessage()함수는 그러고나서 적절한 WindowProc() 함수에 대한 호출을 한다. 운 좋게도, 우리는 걱정해야 할 오직 하나의 WindowProc 함수만을 가지고 있다. 그래서 상황은 상대적으로 간단할 것이다.

WindowProc() 함수가 호출될 때, MSG struct로부터 4개의 정보의 조각들이 보내진다. 이러한 것을 보기 위해 WindowProc() 함수에 대해 prototype을 봐보자.

너가 MSG 구조체의 파라미터들에 대해 이전에 보았다면, 너는 이것을 이미 보았따, 그래서 우리느 ㄴ여기에서 그것들을 다시 다루지 않을 것이다.

우리갸 여기에서 할 것은, 이 함수의 내용이다. 너가 코드로부터 보았듯이, 그것은 프로그램에 정의되는데, 이것은 우리가 그것의 코드를 제공한다는 내용이다.

한 message가 WindowProc에 진입할 때, 우리는 uMsg 인자를 무슨 메세지인지 결정하기 위해 사용할 수 있다. 많은 프로그래머들은 그 메세지를 결정하기 위해 switch() 문을 상요한다. 여기에 너가 이것을 하는 예제가 있다.

여기에서 그 스위치문은 작동시킬 코드를 찾는다. 물론, 우리는 WM_DESTROY message만을 제공하고, 만약 어떠 ㄴ다른 메세지가 보내진다면, 우린느 그것을 무시하는 것을 의미한다. WM_DESTROY 메세지는 윈도우가 닫혀질 때 보내진다. 그래서 윈도우가 끝날 떄, 우리는 우리가 우리의 프로그램을 정리하기 위해 필요한 것 무엇이든 할 수 있다. 지금 당장, 구성되어 있는 모든 것은 그 프로그램에게 우리가 끝났다고 말하는 것이고, 0을 반환하는 것인데, 이것은 모든 것이 정리되었다고 가리키는 것이다. 우리는 다음의 코드로 이것을 한다:

PostQuitMessage() 함수는 WM_QUIT 메세지를 보내는데, 그것은 0의 정수값을 가진다. 만약 너가 너의 main loop에 대해 다시 상기한다면, 너는 GetMessage() 함수가 그 프로그램이 그만 둘 때만 false를 반환한다는 것을 기억할 것이다. 좀 더 구체적으로, 0이 보내질 때만 FALSE를 반환한다. WM_QUIT의 겨웅에서 처럼. 그래서 이 함수가 기본적으로 하는 것은 우리의 프로그램에게 WinMain() 함수를 적절히 끝내라고 말하는 것이다.

그 다음에 우리는 0을 반환한다. 이것은 오히려 중요하다. 왜냐하면 그것은 우리가 다루었던 윈도우즈에 그 메세지를 말하기 때문이다. 만약 우리가 다른 것을 보낸다면, 윈도우즈는 혼란스러울 수 있따.

만약 너가 우리의 프로그램 코드를 더 공부한다면, 너는 설명되어야할 마지막 함수가 있다는 것을 발견할 것이다. DefWindowProc(). 이 함수가 하는 것은, 우리가 다루지 않았던 어떤 메세지들을 다루는 것이다. 요약해서, 그것은 우리가 0을 반환하지 않는 메세지를 다룬다. 우리는 그러므로 그것을 WindowProc() 함수의 끝에 반환하는데, 그것이 우리가 놓친 어떤 것을 잡도록 하기 위해서이다.













댓글 없음:

댓글 쓰기