이번에는 실제로 눈에 보이는 윈도우 창을 띄워보자.
지난 시간에 우리의 Entry point인 WinMain 함수를 살펴보았는데, 그 세부적인 파라미터는 아래에서 확인할 수 있다.
MSDN 링크:
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-winmain
#include <Windows.h>
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
// register window class
/*
윈도우 함수에서 앞으로 자주 볼 방식으로, 함수에 파라미터 몇십개를 일일히 넘겨주는 것보다, 이 데이터들이 들어있는 구조체를 만들어 그 구조체의 포인터를 넘겨주는 방식이 자주 사용된다.
여기서도 WNDCLASSEX라는 struct를 만들어 RegisterClassEx()에 전달하고 있다.
여기서 Ex라는 접미사는 일종의 개량판 느낌으로, WNDCLASSEX는 WNDCLASS에 여러 기능이 추가된(extended) 버전이다.
WNDCLASSEX는 하나의 윈도우 창(window)을 정의하는 용도, 즉 윈도우 클래스를 정의하는 용도로 사용되는데, RegisterClassEx()는 이 프로세스가 해당 윈도우 클래스를 사용한다고 알려주는 역할을 한다.
struct WNDCLASS{
UINT style; //윈도우 클래스 스타일. 비트 연산자를 사용해 지정.
WNDPROC lpfnWndProc; //콜백 프로시저
int cbClsExtra; //윈도우 클래스의 여분 메모리
int cbWndExtra; //윈도우 인스턴스의 여분 메모리
HINSTANCE hInstance; //윈도우 클래스를 등록하는 모듈의 인스턴스 핸들
HICON hIcon; //아이콘 핸들
HCURSOR hCursor; //커서 핸들
HBRUSH hbrBackground; //배경 브러쉬
LPCWSTR lpszMenuName; //메뉴 이름
LPCWSTR lpszClassName; //클래스 이름
};
WNDCLASS에 대한 더 자세한 설명은 http://ehpub.co.kr/tag/registerclass/ 참고.
*/
const auto pClassName = "hw3d"; // 클래스의 이름
// 나중에 다른 함수에서 만들어진 클래스를 찾을때도 사용된다 (id같은 느낌이다)
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof( wc );
wc.style = CS_OWNDC;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = pClassName;
wc.hIconSm = nullptr;
RegisterClassEx( &wc );
// create window instance
/*
위에서 register한 윈도우 클래스로부터 HWND라는 윈도우(창) 인스턴스를 만든다.
MSDN:
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexa
두번째 인자인 lpClassName이 중요한데, 여기에 주어지는 클래스 이름으로 어떤 클래스로부터 인스턴스를 만들지 결정한다.
*/
HWND hWnd = CreateWindowEx(
0,
pClassName,
"Happy Hard Window",
WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
200,200,640,480,
nullptr,nullptr,hInstance,nullptr
);
// show the damn window
// ShowWindow를 호출하지 않으면 실제로 창이 그려지지 않는다
ShowWindow( hWnd,SW_SHOW );
// 창이 꺼지지 않게 루프
while( true );
return 0;
}
잘 작동함을 확인할 수 있다.
뒷 배경이 투명한 이유는 우리가 클래스를 정의할 때 hbrBackground를 nullptr로 정의했기 때문이다. 이걸 바꿔서 창 배경을 까맣게 만들거나 할 수 있다.
그러나 우리의 경우 어차피 d3d에서 렌더링한 내용을 창에 그릴 것이기 때문에 굳이 불필요한 작업을 해줄 필요가 없다.
'computer graphics > DirectX' 카테고리의 다른 글
[D3D Engine] 6. WM_CHAR, Mouse (0) | 2023.03.19 |
---|---|
[D3D Engine] 5. Window Messages (1) | 2023.03.19 |
[D3D Engine] 4. Message loop, WinProc (0) | 2023.03.19 |
[D3D Engine] 2. WinMain (0) | 2023.03.19 |
[D3D Engine] 1. Introduction (0) | 2023.03.19 |