４

・SplashWnd.cpp

```
#include "stdafx.h"
#include "Bootup.h"
#include "SplashWnd.h"

////////////////////////////////////////////////////////////////////////
// スプラッシュウィンドウ
////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC(CSplashWnd, CWnd)

//----------------------------------------------------------------------
// メッセージマップの定義
//----------------------------------------------------------------------

BEGIN_MESSAGE_MAP(CSplashWnd, CWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_TIMER()
	ON_WM_LBUTTONDOWN()
	ON_WM_CLOSE()
	ON_WM_ENDSESSION()
END_MESSAGE_MAP()

//----------------------------------------------------------------------
// リソースを解放する
//----------------------------------------------------------------------

void CSplashWnd::FreeResource()
{
	KillTimer(BOOTUP_END_TIMER_ID);
}

//----------------------------------------------------------------------
// WM_CREATE ハンドラ
//----------------------------------------------------------------------

int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1) {
		return -1;
	}

	BootupProfile* pProfile = ((CBootupApp*) AfxGetApp())->GetProfile();

	// 終了用タイマの設定
	SetTimer(BOOTUP_END_TIMER_ID, pProfile->splashInfo.TimeOut, 0);

	return 0;
}

//----------------------------------------------------------------------
// WM_PAINT ハンドラ
//----------------------------------------------------------------------

void CSplashWnd::OnPaint()
{
	CPaintDC dc(this);

	BootupProfile* pProfile = ((CBootupApp*) AfxGetApp())->GetProfile();
	SplashResource* pSplashResource = ((CBootupApp*) AfxGetApp())->GetSplashResource();

	// 背景を塗りつぶす
	{
		CPen pen;
		pen.CreatePen(PS_SOLID, 1, pProfile->splashInfo.BackgraoundColor);
		CBrush brush;
		brush.CreateSolidBrush(pProfile->splashInfo.BackgraoundColor);

		CPen* pPrevPen = dc.SelectObject(&pen);
		CBrush* pPrevBrush = dc.SelectObject(&brush);
		dc.Rectangle(0, 0, pProfile->splashInfo.Width, pProfile->splashInfo.Height);

		dc.SelectObject(pPrevPen);
		dc.SelectObject(pPrevBrush);

		pen.DeleteObject();
		brush.DeleteObject();
	}

	// ビットマップを描画する
	if (pSplashResource->BackgraoundBitmap.GetSafeHandle()) {
		CDC memDC;
		memDC.CreateCompatibleDC(&dc);

		CRect rect;
		GetClientRect(&rect);

		BITMAP bmpInfo;
		pSplashResource->BackgraoundBitmap.GetBitmap(&bmpInfo);

		CGdiObject* pPrevBitmap = memDC.SelectObject(&pSplashResource->BackgraoundBitmap);
		
		int x = 0;
		int y = 0;
		if (bmpInfo.bmWidth < rect.Width()) {
			x = (rect.Width() - bmpInfo.bmWidth) / 2;
		}
		if (bmpInfo.bmHeight < rect.Height()) {
			y = (rect.Height() - bmpInfo.bmHeight) / 2;
		}

		dc.BitBlt(x, y, bmpInfo.bmWidth, bmpInfo.bmHeight, &memDC, 0, 0, SRCCOPY);
		
		memDC.SelectObject(pPrevBitmap);
	}


	// 文字を表示する
	int prevBkMode = dc.SetBkMode(TRANSPARENT);

	for (int i = 0; i < pProfile->splashInfo.TextInfoList.GetSize(); ++i) {

		TextInfo& textInfo = pProfile->splashInfo.TextInfoList.GetAt(i);

		CFont font;
		LOGFONT logfont;

		ZeroMemory(&logfont, sizeof(logfont));
		logfont.lfHeight = -MulDiv(textInfo.Point, dc.GetDeviceCaps(LOGPIXELSY), 72);
		logfont.lfWeight = textInfo.Weight;
		logfont.lfItalic = (textInfo.Italic) ? TRUE : FALSE;
		_tcscpy_s(logfont.lfFaceName, textInfo.Fontname);

		font.CreateFontIndirect(&logfont);

		CFont* pPrevFont = dc.SelectObject(&font);
		COLORREF prevTextColor = dc.SetTextColor(textInfo.Color);

		dc.TextOut(textInfo.Left, textInfo.Top, textInfo.Caption);

		dc.SelectObject(pPrevFont);
		dc.SetTextColor(prevTextColor);

		font.DeleteObject();
	}

	dc.SetBkMode(prevBkMode);
}

//----------------------------------------------------------------------
// WM_TIMER ハンドラ
//----------------------------------------------------------------------

void CSplashWnd::OnTimer(UINT_PTR nIDEvent)
{
	PostMessage(WM_CLOSE);
	CWnd::OnTimer(nIDEvent);
}

//----------------------------------------------------------------------
// WM_LBUTTONDOWN ハンドラ
//----------------------------------------------------------------------

void CSplashWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
	PostMessage(WM_CLOSE);
	CWnd::OnLButtonDown(nFlags, point);
}

//----------------------------------------------------------------------
// WM_CLOSE ハンドラ
//----------------------------------------------------------------------

void CSplashWnd::OnClose()
{
	FreeResource();
	CWnd::OnClose();
}

//----------------------------------------------------------------------
// WM_ENDSESSION ハンドラ
//----------------------------------------------------------------------

void CSplashWnd::OnEndSession(BOOL bEnding)
{
	CWnd::OnEndSession(bEnding);
	FreeResource();
}