[DirectX 11] 4. DirectX 창 만들기

psj98·2022년 10월 19일
0
post-thumbnail

RenderWindow.h 파일 생성 및 코드 작성

  1. 솔루션 탐색기 클릭
  2. 헤더 파일 우클릭
  3. 추가 -> 새 항목 클릭
  4. 헤더 파일 클릭 후, RenderWindow.h 입력 후, 추가

RenderWindow.h

#pragma once
#include "ErrorLogger.h"

class RenderWindow
{
public:
	bool Initialize(HINSTANCE hInstance, string window_title, string window_class, int width, int height);
	bool ProcessMessages();
	~RenderWindow();

private:
	void RegisterWindowClass();
	HWND handle = NULL;
	HINSTANCE hInstance = NULL;
	string window_title = "";
	wstring window_title_wide = L"";
	string window_class = "";
	wstring window_class_wide = L"";
	int width = 0;
	int height = 0;
};

RenderWindow.cpp 파일 생성 및 코드 작성

  1. 솔루션 탐색기 클릭
  2. 헤더 파일 우클릭
  3. 추가 -> 새 항목 클릭
  4. 헤더 파일 클릭 후, RenderWindow.cpp 입력 후, 추가

RenderWindow.cpp

1. Initialize 함수

생성할 창의 이름, 제목 등 특징을 설정하고 창을 띄우는 함수
만약, 핸들이 없으면 경고창을 띄움

#include "RenderWindow.h"

/* 초기화 */
bool RenderWindow::Initialize(HINSTANCE hInstance, string window_title, string window_class, int width, int height)
{
	this->hInstance = hInstance;
	this->width = width;
	this->height = height;
	this->window_title = window_title;
	this->window_title_wide = StringConverter::StringToWide(this->window_title); // wstring 타입으로 변경
	this->window_class = window_class;
	this->window_class_wide = StringConverter::StringToWide(this->window_class); // wstring 타입으로 변경

	this->RegisterWindowClass(); // 렌더링 할 윈도우 특징 설정

	/* 확장 윈도우 스타일 */
	this->handle = CreateWindowEx(0, // 생성 중인 윈도우의 확장 스타일
		this->window_class_wide.c_str(), // 윈도우 클래스 이름
		this->window_title_wide.c_str(), // 윈도우 제목
		WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, // 윈도우 스타일
		0, // 윈도우 수평 위치
		0, // 윈도우 수직 위치
		this->width, // 윈도우 너비
		this->height, // 윈도우 높이
		NULL, // 생성중인 윈도우의 부모에 대한 핸들
		NULL, // 메뉴에 대한 핸들 or 윈도우 스타일에 따라 자식 윈도우 식별자 지정
		this->hInstance, // 윈도우와 연결한 모듈의 인스턴스에 대한 핸들
		nullptr); // 윈도우를 생성하기 위한 파라미터

	/* 핸들이 없으면 경고창 띄움 */
	if (this->handle == NULL)
	{
		ErrorLogger::Log(GetLastError(), "CreateWindowEX Failed for window: " + this->window_title);
		return false;
	}

	/* 창을 띄우고 포커스를 해당 창으로 설정 */
	ShowWindow(this->handle, SW_SHOW); // 지정된 창의 표시 상태 설정
	SetForegroundWindow(this->handle); // 지정된 창을 만든 스레드를 포그라운드로 가져와 창을 활성화
	SetFocus(this->handle); // 지정된 창에 포커스 설정

	return false;
}

CreateWindowEx 함수

CreateWindowEx(DWORD dwExStyle,
               LPCSTR lpClassName, LPCSTR lpWindowName,
               DWORD dwStyle,
               int X, int Y,
               int nWidth, int nHeight,
               HWND hWndParent, HMENU hMenu,
               HINSTANCE hInstance,
               LPVOID lpParam
);
- dwExStyle : 생성 중인 창의 확장 스타일
- lpClassName : 윈도우 클래스 이름
- lpWindowName : 윈도우 제목
- dwStyle : 윈도우 스타일
	* WS_CAPTION : 제목 표시줄
    * WS_MINIMIZEBOX : 최소화 버튼
    * WS_SYSMENU : 제목 표시줄의 창 메뉴
- X, Y : 윈도우 수평/수직 위치
- nWidth, nHeight : 윈도우 너비/높이
- hWndParent : 생성중인 윈도우의 부모에 대한 핸들
- hMenu : 메뉴에 대한 핸들 or 윈도우 스타일에 따라 자식 윈도우 식별자 지정
- hInstance : 윈도우와 연결한 모듈의 인스턴스에 대한 핸들
- lpParam : 윈도우를 생성하기 위한 파라미터

CreateWindowEx 참고 링크


2. RegisterWindowClass 함수

렌더링할 창의 특징을 설정하는 함수

/* 렌더링할 윈도우 특징 설정 */
void RenderWindow::RegisterWindowClass()
{
	WNDCLASSEX wc; // 윈도우 클래스

	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // 윈도우 클래스의 스타일
	wc.lpfnWndProc = DefWindowProc; // 윈도우 프로시저의 함수명 - WndProc에서 처리하지 않은 나머지 메시지에 관한 처리를 해줌
	wc.cbClsExtra = 0; // 윈도우 클래스 구조에 할당할 메모리 (사용 x)
	wc.cbWndExtra = 0; // 윈도우 인스턴스에 할당할 메모리 (사용 x)
	wc.hInstance = this->hInstance; // 인스턴스 핸들 전달
	wc.hIcon = NULL; // 아이콘 핸들
	wc.hIconSm = NULL; // 작은 아이콘 핸들
	wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 커서 핸들
	wc.hbrBackground = NULL; // 배경 브러시 핸들
	wc.lpszMenuName = NULL; // 메뉴 리소스 - 메뉴에 대해 NULL로 종료된 문자열에 대한 포인터
	wc.lpszClassName = this->window_class_wide.c_str(); // 윈도우 클래스 이름에 대해 NULL로 종료된 문자열에 대한 포인터
	wc.cbSize = sizeof(WNDCLASSEX); // 윈도우 클래스 구조체의 크기

	RegisterClassEx(&wc); // 윈도우 클래스 등록
}

WNDCLASSED 구조체

- cbSize : 윈도우 클래스 구조체의 크기
- style : 윈도우 클래스 스타일
- lpfnWndProc : 창 프로시저에 대한 포인터 - WndProc에서 처리하지 않은 나머지 메시지에 관한 처리를 해줌
- cbClsExtra : 윈도우 클래스 구조에 할당할 메모리 (사용 x)
- cbWndExtra : 윈도우 인스턴스에 할당할 메모리 (사용 x)
- hInstance : 인스턴스 핸들 전달
- hIcon : 아이콘 핸들
- hCursor : 커서 핸들
- hbrBackground : 배경 브러시 핸들
- lpszMenuName : 메뉴 리소스 - 메뉴에 대해 NULL로 종료된 문자열에 대한 포인터
- lpszClassName : 윈도우 클래스 이름에 대해 NULL로 종료된 문자열에 대한 포인터
- hIconSm : 작은 아이콘 핸들

WNDCLASSEX 참고 링크


3. ProcessMessages 함수

메시지를 처리해주는 함수

bool RenderWindow::ProcessMessages()
{
	/* 윈도우 메시지 핸들 */
	MSG msg;
	ZeroMemory(&msg, sizeof(MSG)); // 메모리 구조 초기화

	if (PeekMessage(&msg, // 메시지 정보를 수신하는 MSG 구조에 대한 포인터
		this->handle, // 메시지를 검색할 창에 대한 핸들
		0, // 검사할 메시지 범위의 첫 번째 메시지 값
		0, // 검사할 메시지 범위의 마지막 메시지 값
		PM_REMOVE)) // 메시지 처리 방법
	{
		TranslateMessage(&msg); // 가상 키 메시지를 문자 메시지로 변환
		DispatchMessage(&msg); // 창 프로시저에 메시지를 전달
	}

	/* 창이 닫혔는지 체크 */
	if (msg.message == WM_NULL)
	{
		if (!IsWindow(this->handle)) // 창이 닫힌 경우
		{
			this->handle = NULL;
			UnregisterClass(this->window_class_wide.c_str(), this->hInstance); // 창 클래스의 등록을 취소
			return false;
		}
	}

	return true;
}

4. ~RenderWindow 함수

RenderWindow 함수의 소멸자

/* 소멸자 */
RenderWindow::~RenderWindow()
{
	if (this->handle != NULL)
	{
		UnregisterClass(this->window_class_wide.c_str(), this->hInstance);
		DestroyWindow(handle);
	}
}

main.cpp 수정

#include "RenderWindow.h" // 헤더 파일 변경

// 아까 추가한 라이브러리를 가져옴
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "DirectXTK.lib")

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, // 인스턴스에 대한 핸들
	_In_opt_ HINSTANCE hPrevInstance, // 사용 X
	_In_ LPWSTR lpCmdLine, // 커맨드 라인을 유니코드 문자열로 포함
	_In_ int cCmdShow) // 기본 응용 프로그램 창이 최소화, 최대화 또는 정상적으로 표시되는지 여부를 나타내는 플래그
{
	/* 에러 창 띄우기
		HRESULT hr = E_INVALIDARG; // 올바르지 않은 매개 변수
		ErrorLogger::Log(hr, "FAILURE");
	*/

	RenderWindow rw;
	rw.Initialize(hInstance, "Title", "MyWindowClass", 800, 600); // 창 크기를 800, 600으로 설정

	/* 창을 닫을 때까지 열어둠 */
	while (rw.ProcessMessages() == true) {} // 창을 끄는 경우 ProcessMessages에서 false가 반환되어 종료됨

	return 0;
}

실행

profile
SSAFY 9기

0개의 댓글