DirectX 3D 4일차 - 윈도우 메시지 사용해보기
오늘은 Window클래스와 하위 클래스인 WindowClass가 추가되었습니다.
Window 클래스는 저희가 WinMain 함수에서 구현을 했었던 여러 작업들(윈도우 클래스 등록, 윈도우 객체 생성)을 클래스로 구현을 하면서 캡슐화를 시킨것입니다.
WindowClass의 헤더파일입니다.
일단 선언되어 있는 것을 차례대로 본다면 public으로 GetName과, GetInstance라는 함수 2개가 존재하는데요. 밑에 private으로 선언된 영역에 hInstance와 wndClassName을 반환하는 함수인것 같습니다.
그리고 WindowClass의 private 영역을 본다면 생성자와 소멸자, 연산자와 싱글톤을 위한 static 변수와 이름, 인스턴스 등이 있습니다.
먼저 윈도우 클래스의 생성자를 보시면 저희가 WinMain에서 했던 Window class를 등록하는 과정이랑 완전히 똑같은 것을 보실 수 있으십니다. 다른점은 이제 WindowClass 안에 클래스 변수 같은 것을 갖고 와서 class name같은 것을 설정해주는 정도 인것 같습니다.
다음은 Window클래스에 대해 알아보겠습니다.
헤더파일에 클래스 public 부분을 보면 생성자, 소멸자, 연산자 등이 있고,
private 부분에는 너비와 높이, 윈도우를 처리하는 핸들러가 하나 있고 WndProc의 역할을 하는 함수들이 있는것 같습니다.
우선 Window의 생성자를 보면
저희가 저번영상까지 WinMain에 작성했었던 윈도우 인스턴스를 생성하고 보여주는 과정이 적혀있습니다. 다른점이 있다면 저희는 WinMain에서 임의로 너비와 높이를 조절을 했었는데 여기서는 RECT 를 이용해서 지정을 했고, 윈도우 클래스의 이름을 WindowClass 로부터 가져왔습니다,
그리고 마지막에 lpParam의 nullptr이 아닌 window클래스로 만든 인스턴스 자신 자체를 넘겨주었습니다. 영상에서는 이 부분에 대해서 추후 다룰 예정이라고 합니다.
참고로 CW_USEDEFAULT는 커널에 의해 기본값으로 지정한다는 의미입니다. x, y 위치에 CW_USEDEFAULT가 있으므로 위치를 커널이 알아서 정하는 것으로 볼 수 있네요.
다음으로는 WndProc 역할을 하는 HandleMsgSetup인데요 WindowClass에서 윈도우 클래스를 등록을 할 때 WndProc값으로 넘겨주었던 함수입니다.
먼저 msg가 WM_NCCREATE인지를 검사합니다. MSDN사이트에 들어가서 보니까 윈도우 창이 생성되었을 때 WM_CREATE보다 먼저 보내지는 메시지라고 하네요. 즉 저 조건문 안에 있는 내용은 처음 윈도우 창을 생성하였을 때 동작하는 함수라는 말이 됩니다. 그리고 WM_NCCREATE는 파라미터로 wParam과 lParam 2개가 있는데 wParam은 사용하지 않고 lParam을 사용하기 위해서 작성되었던 것이 생성자에서 CreateWindow를 할 때 자기 자신을 인수로 보내준 것이라고 하네요, 윈도우 메시지를 처리하는 메커니즘과 윈도우 인스턴스와의 연결이라고 영상에서는 표현하고 있습니다.
계속 보면 CREATESTRUCTW라는 구조체로 pCreate를 생성을 할 때 lParam 값을 이용해서 생성하는 것을 볼 수 있습니다. 실제로 CreateWindow 함수를 MSDN 사이트에 들어가서 보면 CREATESTRUCTW 구조체 포인터로 값을 넘겨주라는 것을 확인할 수 있습니다. lParam값을 가지고서 CREATESTRUCTW룰 생성(초기화) 후
SetWindowLongPtr 함수는 지정된 윈도우의 속성을 변경합니다. 저희는 hWnd 윈도우 창을 GWLP_USERDATA 를 사용해서 창과 관련된 사용자의 데이터를 윈도우 인스턴스의 추가 메모리에 저장할 수 있습니다.
그리고 저희가 lParam을 기반으로 생성했던 윈도우 클래스인 pWnd로 변경을 해줍니다.
두번째 SetWindowLongPtr 함수에서는 사용하는 윈도우 프로시저를 변경해줍니다. 저희가 윈도우 클래스 등록시 사용했던 윈도우 프로시저인 HandleMsgSetup은 말 그대로 초기에 윈도우 생성시에만 사용하는 윈도우 프로시저 입니다. 이제 윈도으 프로시저를 HandleMsgThunk 함수로 변경을 해주어야 합니다.
잠깐 지금까지의 과정을 요약해보면 윈도우창 생성시 전달받은 윈도우 클래스의 정보를 가지고서 유저 데이터를 저장하고 새로운 프로시저로 바꾸어 준다정도가 되겠네요.
HandleMsgThunk는 새로운 윈도우 프로시저입니다.
handleMsgThunk 함수에서 아까 SetWindowLongPtr을 사용했던 유저 데이터를 불러와서 pWnd를 생성합니다.
그리고 해당 정보를 가진 Window class와 메시지를 가지고 HandleMsg에서 치리 후 Default Window Proc으로 메시지를 전달해줍니다.
참고 사이트
docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccreate
WM_NCCREATE message (Winuser.h) - Win32 apps
Sent prior to the WM\_CREATE message when a window is first created.
docs.microsoft.com