・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();
}