初めての関数化
最後に作ったウィンドウのプログラムを関数化してみましょう。
先ずmain.cppを作った時と同じ手順でWindow.cppとWindow.hを作りましょう。
このようにファイルが2つ追加された状態にします。
ではまずヘッダーファイルから書いていきましょう。
ヘッダーファイルには他のプログラムから使用したい関数を宣言していきます。
Window.h
// 多重インクルード対策 #pragma once #include <windows.h> // シンプルなウィンドウの作成 bool CreateSimpleWindow(const TCHAR* pName, int x, int y, int width, int height); // メッセージの更新 bool UpdateWindowMessage(void); // 終了通知が来ているか? bool IsQuitMessage(void); // ウィンドウハンドルの取得 HWND GetWindowHandle(void);
次はcppファイルです。
cppファイルはmain.cppと同じようにプログラムの処理を記載していきます。
Window.cpp
// 作成したWindow.hを含める
#include "Window.h"
// ウィンドウハンドル
HWND g_hWnd = NULL;
// 終了通知が来ているか?
bool g_isQuitMessage = false;
// ウインドウプロシージャー
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
switch( uiMsg )
{
case WM_CLOSE: // 閉じる際にWindowを破棄する
DestroyWindow(hWnd);
return 0;
case WM_DESTROY: // プログラムの終了を通知する
PostQuitMessage(0);
return 0L;
}
// 既定のウィンドウプロシージャを呼び出す
return DefWindowProc(hWnd, uiMsg, wParam, lParam);
}
// シンプルなウィンドウの作成
bool CreateSimpleWindow(const TCHAR* pName, int x, int y, int width, int height)
{
WNDCLASSEX wcex;
// ウインドウの設定
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = TEXT("DirectX9 Sample");
wcex.hIcon = LoadIcon(NULL, IDC_ARROW);
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassExW(&wcex);
DWORD dwStyle = WS_OVERLAPPEDWINDOW;
RECT Rect;
Rect.left = 0;
Rect.top = 0;
Rect.right = width;
Rect.bottom = height;
// ウィンドウのスタイルに合わせた適切なサイズを取得する
AdjustWindowRect(&Rect, dwStyle, false);
width = Rect.right - Rect.left;
height = Rect.bottom - Rect.top;
// ウインドウの生成
g_hWnd = CreateWindow(wcex.lpszClassName,
pName,
dwStyle,
x,
y,
width,
height,
NULL,
NULL,
GetModuleHandle(NULL),
NULL);
if( g_hWnd == NULL )
{
return false;
}
// ウインドウの表示
ShowWindow(g_hWnd, SW_SHOW);
UpdateWindow(g_hWnd);
return true;
}
// メッセージの更新
bool UpdateWindowMessage(void)
{
MSG msg;
// メッセージが存在するか確認
if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
{
// 終了通知が来ている場合は抜ける
if( msg.message == WM_QUIT )
{
g_isQuitMessage = true;
}
else
{
// メッセージをウインドウプロシージャに転送
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
return false;
}
// 終了通知が来ているか?
bool IsQuitMessage(void) { return g_isQuitMessage; }
// ウィンドウハンドルの取得
HWND GetWindowHandle(void) { return g_hWnd; }
これで先ほどmain.cppに書いたプログラムを関数化することが出来ました。
このように処理を関数化することでプログラムを用途ごとに切り分けて分かりやすくすることができます。
又、他の場所で使いまわしたい際に関数を呼び出すだけで使えるようになります。
では最後にmain.cppの中身を関数化したものに置き換えてみましょう。
main.cpp
#include "Window.h"
// エントリーポイント
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// ウィンドウの生成
if( !CreateSimpleWindow(TEXT("DirectX9"), 0, 0, 640, 480) )
{
return false;
}
// メインループ
while( !IsQuitMessage() )
{
// メッセージの更新
UpdateWindowMessage();
}
return 0;
}
関数化することでこんなにWinMain関数がスッキリしました!
コードも読みやすくなるので、プログラムを作る際はどういった単位で関数化するかを考えて作っていきましょう。
今回はスッキリしたところでこの辺りまでにします。
次回『始めてのDirectX9』へ続く。
