【C++】DirectX(Windows)アプリ作成時のウィンドウ雛形

![directx.jpg](https://qiita-image-store.s3.amazonaws.com/0/127402/dcf2af32-dddb-573e-f756-1f2a1cc988b5.jpeg)


完全に個人用メモです。

# エントリポイント
```cpp:winmain.cpp
#include "DXApp.h"

class TestApp : public DXApp {
public:
	TestApp(HINSTANCE hInstance);
	~TestApp();

	bool Init() override;
	void Update(float dt) override;
	void Render(float dt) override;
};

TestApp::TestApp(HINSTANCE hInstance) : DXApp(hInstance) {

}

TestApp::~TestApp() {

}

bool TestApp::Init() {
	return DXApp::Init();
}

void TestApp::Update(float dt) {

}

void TestApp::Render(float dt) {

}

int WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd) {

	TestApp tApp(hInstance);

	if (!tApp.Init()) {
		return 1;
	}

	return tApp.Run();
}
```

# ウィンドウ構成クラス

```cpp:DXApp.h
#pragma once

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <string>

class DXApp
{
public:
	DXApp(HINSTANCE hInstance);
	virtual ~DXApp();

	// Main Application Loop
	int Run();

	// Framework method
	virtual bool Init();
	virtual void Update(float dt) = 0;
	virtual void Render(float dt) = 0;
	virtual LRESULT MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lparam);

protected:

	// WIN32 ATTRIBUTES
	HWND			m_hAppWnd;
	HINSTANCE		m_hAppInstance;
	UINT			m_ClientWidth;
	UINT			m_ClientHeight;
	std::string		m_AppTitle;
	DWORD			m_WndStyle;

protected:
	bool InitWindow();
};
```

```DXApp:DXApp.cpp
#include "DXApp.h"

namespace {
	DXApp* g_pApp = nullptr;
}

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	if (g_pApp) return g_pApp->MsgProc(hwnd, msg, wParam, lParam);
	else return DefWindowProc(hwnd, msg, wParam, lParam);
}

DXApp::DXApp(HINSTANCE hInstance)
{

	m_hAppInstance = hInstance;
	m_hAppWnd = NULL;
	m_ClientWidth = 800;
	m_ClientHeight = 600;
	m_AppTitle = "DirectX11 Application";
	m_WndStyle = WS_OVERLAPPEDWINDOW;
	g_pApp = this;	// 閉じたら消える
}


DXApp::~DXApp()
{

}

bool DXApp::Init() {
	if (!InitWindow()) {
		return false;
	}
	
	return true;
}

bool DXApp::InitWindow() {
	WNDCLASSEX wcex;
	ZeroMemory(&wcex, sizeof(WNDCLASSEX));
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.hInstance = m_hAppInstance;
	wcex.lpfnWndProc = MainWndProc;
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = "DXXAPPWNDCLASS";
	wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	
	if (!RegisterClassEx(&wcex)) {
		OutputDebugString("\nFailed to create window class");
		return false;
	}

	RECT r = { 0, 0, m_ClientWidth, m_ClientHeight };
	AdjustWindowRect(&r, m_WndStyle, FALSE);
	UINT width = r.right - r.left;
	UINT height = r.bottom - r.top;

	UINT x = GetSystemMetrics(SM_CXSCREEN) / 2 - width / 2;
	UINT y = GetSystemMetrics(SM_CYSCREEN) / 2 - height / 2;

	m_hAppWnd = CreateWindow("DXXAPPWNDCLASS", m_AppTitle.c_str(), m_WndStyle, x, y, width, height, NULL, NULL, m_hAppInstance, NULL);
	if (!m_hAppWnd) {
		OutputDebugString("\nFailed to create window class");
		return false;
	}

	ShowWindow(m_hAppWnd, SW_SHOW);
	return true;
}

int DXApp::Run() {

	// Main Message Loop
	MSG msg = { 0 };

	while (WM_QUIT != msg.message) {
		if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else {
			// Update
			Update(0.0f);

			// Render
			Render(0.0f);
		}
	}

	return static_cast<int>(msg.wParam);
}

LRESULT DXApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
}
```