アットウィキロゴ

ウィンドウの表示(クラス化)

ウインドウの表示(基本編)をリファクタリングしていきます。

"lib"ディレクトリを作り、Window.h,Window.cppを作成します。

Window.h


/***********************************************************
    ウィンドウクラス
    - HWNDのラッパークラス
***********************************************************/

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

class Window
{
// ---------------------------------------------------------
// 生成と破棄
private:
    Window(HWND);
public:
    static Window* Create( const std::wstring& title, int width, int height );

// ---------------------------------------------------------
// 基本機能
public:
    // Windowsメッセージを処理
    bool ProcessMessage() const ;

    HWND GetHwnd() const { return hwnd; }
// ---------------------------------------------------------
// メンバ変数
private:
    HWND hwnd;
};


Window.cpp


/***********************************************************
    ウィンドウクラス
    - HWNDのラッパークラス
***********************************************************/

#include "Window.h"

// ---------------------------------------------------------
// 生成と破棄
// ---------------------------------------------------------
// コンストラクタ
Window::Window(HWND hwnd)
    : hwnd(hwnd)
{}

// 生成
Window* Window::Create( const std::wstring& title, int width, int height )
{
    const std::wstring class_name = TEXT("GameClass");
    const DWORD style = WS_OVERLAPPEDWINDOW & ~( WS_MAXIMIZEBOX | WS_THICKFRAME );
    const DWORD exstyle = 0;
	const HINSTANCE instance = GetModuleHandle( nullptr );
    const int default_dpi = 96;

    //ウィンドウクラスの登録
    WNDCLASSEX wc = { sizeof( WNDCLASSEX ) };
    wc.hInstance = instance;
    wc.lpszClassName = class_name.c_str();
    wc.lpfnWndProc = DefWindowProc;
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wc.hIcon = static_cast< HICON >(
		LoadImage( nullptr, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED )
        );
    wc.hIconSm = wc.hIcon;
    wc.hCursor = static_cast< HCURSOR >(
        LoadImage( nullptr, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED )
        );
    wc.hbrBackground = static_cast< HBRUSH >(
        GetStockObject( WHITE_BRUSH )
        );
    if( !RegisterClassEx( &wc ) ) return nullptr;

    // ウィンドウサイズからクライアント領域を計算
    HDC hdc = GetDC(NULL);
    int client_width = static_cast<int>(width * GetDeviceCaps(hdc, LOGPIXELSX) / default_dpi);
    int client_height = static_cast<int>(height * GetDeviceCaps(hdc, LOGPIXELSY) / default_dpi);
    ReleaseDC(NULL, hdc);

    RECT rect = { 0, 0, client_width, client_height };
    AdjustWindowRectEx( &rect, style, FALSE, exstyle );

    // ウィンドウ生成
    HWND hwnd = CreateWindowEx(
        exstyle, class_name.c_str(), title.c_str(), style,
        CW_USEDEFAULT, CW_USEDEFAULT,
        rect.right - rect.left, rect.bottom - rect.top,
        nullptr, nullptr, instance, nullptr 
        );
    if( hwnd == nullptr ) return nullptr;
    ShowWindow( hwnd, SW_SHOW );

    Window* window = new Window( hwnd );
    return window;
}

// ---------------------------------------------------------
// 基本機能
// ---------------------------------------------------------

// Windowsメッセージを処理する
bool Window::ProcessMessage() const
{
    if( IsWindow(hwnd)==FALSE ) return false;

    MSG msg;
    ZeroMemory(&msg, sizeof(msg));

    if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    {
        // ウィンドウが閉じられた
        if( msg.message == WM_QUIT ) return false;

        TranslateMessage( &msg );       // キーボード関連のイベント
        DispatchMessage( &msg );        // ウィンドウプロシージャの呼び出し
    }

    return true;
}


main.cpp


/***********************************************************
    [[ウィンドウの表示]](クラス化)
***********************************************************/

#include <cstdlib>
#include <iostream>
#include <string>
#include "lib\Window.h"

#define SAFE_DELETE(o) {if(o)delete o;o=nullptr;}

// ウィンドウ
Window* window;

// エントリーポイント
void main()
{
    // メモリリークの検出を有効化
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    try {

        // ウィンドウの作成
        if( !(window = Window::Create( TEXT("Sample"), 640, 480 )) )
            throw std::runtime_error("ウィンドウの作成に失敗しました。");

        // メインループ
        while( window->ProcessMessage() )
        {
            ; // TODO:1フレームの処理
        }

    }
    // エラー処理
    catch( std::exception e ){
        MessageBoxA( nullptr, e.what(), "error", MB_OK );
    }

    // ウィンドウの解放
    SAFE_DELETE(window);

    // アプリケーション終了
    exit(EXIT_SUCCESS);
}

最終更新:2013年11月18日 12:26