Published 2020. 11. 12. 05:10

ATL은 기본적으로 Win32 API에서 상속을 받았지만, 템플릿 인터페이스가 구현되어있다. 표준 c++에서 제공하지 않는 super 기능을 가지고 있어, 참으로 신기한 친구이다.

 

#include "Precompiled.h"
using namespace D2D1;
using namespace Microsoft::WRL;

struct SampleWindow :
	CWindowImpl<SampleWindow, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>> {

	ComPtr<ID2D1Factory> m_factory;
	ComPtr<ID2D1HwndRenderTarget> m_target;


	DECLARE_WND_CLASS_EX(L"window class name", CS_HREDRAW | CS_VREDRAW, -1);

	BEGIN_MSG_MAP(SampleWindow)
		MESSAGE_HANDLER(WM_PAINT, PaintHandler)
		MESSAGE_HANDLER(WM_DESTROY, DestroyHandler)
		MESSAGE_HANDLER(WM_SIZE, SizeHandler)
		MESSAGE_HANDLER(WM_DISPLAYCHANGE, DisplayChangeHandler)
	END_MSG_MAP()
	
	LRESULT DisplayChangeHandler(UINT, WPARAM, LPARAM, BOOL&) {
		Invalidate();
		return 0;
	}

	LRESULT SizeHandler(UINT, WPARAM, LPARAM lparam, BOOL&) {
		if (m_target) {
			if (S_OK != m_target->Resize(SizeU(LOWORD(lparam), HIWORD(lparam)))) {
				m_target.Reset();
			}
		}
		return 0;
	}

	LRESULT PaintHandler(UINT, WPARAM, LPARAM, BOOL&) {
		PAINTSTRUCT ps;
		VERIFY(BeginPaint(&ps));
		TRACE(L"Paint!\n");
		Render();
		EndPaint(&ps);
		return 0;
	}

	LRESULT DestroyHandler(UINT, WPARAM, LPARAM, BOOL&) {
		PostQuitMessage(0);
		return 0;
	}

	void Invalidate() {
		VERIFY(InvalidateRect(nullptr, false));
	}

	void Create() {
		D2D1_FACTORY_OPTIONS fo = {};
#ifdef DEBUG
		fo.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#endif

		HR(D2D1CreateFactory(
				D2D1_FACTORY_TYPE_SINGLE_THREADED, 
				fo, 
				m_factory.GetAddressOf()));

		CreateDeviceIndependentResources();

		VERIFY(__super::Create(nullptr, 0, L"title"));
	}

	void CreateDeviceIndependentResources() {
		
	}

	void CreateDeviceResources() {
	
	}

	void Render() {
		if (!m_target) {
			RECT rect;
			VERIFY(GetClientRect(&rect));
			auto size = SizeU(rect.right, rect.bottom);

			HR(m_factory->CreateHwndRenderTarget(
				RenderTargetProperties(),
				HwndRenderTargetProperties(m_hWnd, size),
				m_target.GetAddressOf()));

			CreateDeviceResources();
		}

		if (!(D2D1_WINDOW_STATE_OCCLUDED & m_target->CheckWindowState())) {
			m_target->BeginDraw();
			Draw();
			if (D2DERR_RECREATE_TARGET == m_target->EndDraw()) {
				m_target.Reset();
			}
		}
	}
	void Draw() {
		m_target->Clear(ColorF(1.0f, 1.0f, 0.0f));
	}
};

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) {
	
	SampleWindow window;
	window.Create();
	
	MSG message;
	BOOL result;
	while (result = GetMessage(&message, 0, 0, 0)) {
		if (result != -1) {
			DispatchMessage(&message);
		}
	}
}

'삽질' 카테고리의 다른 글

Vector Identity  (0) 2022.07.21
좌표계  (0) 2022.07.15
분산 문제  (0) 2022.07.12
[C++/WinRT] Core 데스크탑 앱 "Hello World" example  (0) 2021.01.06
ATL 스켈레톤 윈도우  (0) 2020.10.30
복사했습니다!