第4章 モジュール分割

4-2 WinMain.cppからDirectDraw関係の処理を取り出す

まず、DirectDraw関係の関数を、別のソース「myDraw.cpp」に移そう。まずはDDrawSamp02を開いておく。

(a) myDraw.cppの新規作成

  1. 「プロジェクト」→「プロジェクトへ追加」→「新規作成」を選択
  2. C++ソースファイルを選択し、ファイル名にmyDraw.cppと入力し、位置がプロジェクトのフォルダになっていることを確認して、OKボタンをクリック
  3. myDraw.cppに、WinMain.cppと同じヘッダ・ファイルをインクルードする
    //=============================================================================
    //	DirectDraw関係の自作関数群
    //=============================================================================
    #include <windows.h>
    #include <windowsx.h>
    #include <stdio.h>
    #include <ddraw.h>
    #include "ddutil.h"
  4. WinMain.cppからDirectDrawオブジェクト関係のプロトタイプ宣言をコピーし、myDraw.cppに貼り付けたあと、次のように修正する。
    staticを付けたのはこのプログラムの中でしか使われない関数という意味である。
    逆にstaticが付いていない関数は他のプログラムから使われるということになる。
    //-----------------------------------------------------------------------------
    // プロトタイプ宣言
    //-----------------------------------------------------------------------------
    HRESULT InitializeDraw(HWND);
    static HRESULT InitFail(HWND, HRESULT, LPCTSTR, ...); 
    void ReleaseDraw(void);
  5. WinMain.cppからDirectDrawオブジェクト関係のグローバル変数をコピーし、myDraw.cppに貼り付けたあと、次のように修正する。
    //-----------------------------------------------------------------------------
    // 外部変数(元)
    //-----------------------------------------------------------------------------
    LPDIRECTDRAW7 g_pDD = NULL;                 // DirectDraw オブジェクト
    LPDIRECTDRAWSURFACE7 g_pDDSPrimary = NULL;  // プライマリ・サーフェイス
    LPDIRECTDRAWSURFACE7 g_pDDSBack = NULL;     // バック・サーフェイス 
    LPDIRECTDRAWSURFACE7 g_pDDSStart = NULL;    // スタート画像用サーフェイス
    LPDIRECTDRAWSURFACE7 g_pDDSGame = NULL;     // ゲーム画像用サーフェイス
    
    //-----------------------------------------------------------------------------
    // グローバル変数
    //-----------------------------------------------------------------------------
    static LPDIRECTDRAWPALETTE g_pDDPal = NULL;  // プライマリ・サーフェイス・パレット
    static char szStartBmp[] = "STARTBMP";       // スタート画像リソース名
    static char szGameBmp[] = "GAMEBMP";         // ゲーム画像リソース名
  6. WinMain.cppからDirectDraw関係の関数(InitializeDraw、InitFail、ReleaseDraw)をmyDraw.cppに移動(WinMain.cppからは削除)し、InitFail関数の頭にstaticを付ける。
    //-----------------------------------------------------------------------------
    // 関数名 : InitFail()
    // 機能概要: 初期化に失敗したときのメッセージ表示関数
    // 引数例 : InitFail(hWnd,hRet,"Err String");                      文字列の表示
    //                         InitFail(hWnd,hRet,"Err Code %d %d", code, err); 書式指定の表示
    // 戻り値 : hRetの値(エラーコード)
    //-----------------------------------------------------------------------------
    static HRESULT InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError,...)
    {
        char        szBuff[128];
        va_list     vl;

[完成後のmyDraw.cpp]

//=============================================================================
//      DirectDraw関係の自作関数郡
//=============================================================================
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <ddraw.h>
#include "ddutil.h"

//-----------------------------------------------------------------------------
// プロトタイプ宣言
//-----------------------------------------------------------------------------
HRESULT InitializeDraw(HWND);
static HRESULT InitFail(HWND, HRESULT, LPCTSTR, ...); 
void ReleaseDraw(void);

//-----------------------------------------------------------------------------
// 外部変数(元)
//-----------------------------------------------------------------------------
LPDIRECTDRAW7 g_pDD = NULL;                                     // DirectDraw オブジェクト
LPDIRECTDRAWSURFACE7 g_pDDSPrimary = NULL;      // プライマリ・サーフェイス
LPDIRECTDRAWSURFACE7 g_pDDSBack = NULL;         // バック・サーフェイス 
LPDIRECTDRAWSURFACE7 g_pDDSStart = NULL;        // スタート画像用サーフェイス
LPDIRECTDRAWSURFACE7 g_pDDSGame = NULL;         // ゲーム画像用サーフェイス

//-----------------------------------------------------------------------------
// グローバル変数
//-----------------------------------------------------------------------------
static LPDIRECTDRAWPALETTE g_pDDPal = NULL;     // プライマリ・サーフェイス・パレット
static char szStartBmp[] = "STARTBMP";          // スタート画像リソース名
static char szGameBmp[] = "GAMEBMP";            // ゲーム画像リソース名

//-----------------------------------------------------------------------------
// 関数名 : InitializeDraw() 
// 機能概要: Direct Draw オブジェクトの生成
// 戻り値 : 正常終了のとき:DD_OK、異常終了のとき:エラーコード
//-----------------------------------------------------------------------------
HRESULT InitializeDraw(HWND hWnd)
{
    ・
    ・
    ・

}

//-----------------------------------------------------------------------------
// 関数名 : InitFail()
// 機能概要: 初期化に失敗したときのメッセージ表示関数
// 引数例 : InitFail(hWnd,hRet,"Err String");                      文字列の表示
//                         InitFail(hWnd,hRet,"Err Code %d %d", code, err); 書式指定の表示
// 戻り値 : hRetの値(エラーコード)
//-----------------------------------------------------------------------------
static HRESULT InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError,...)
{
    ・
    ・
    ・

}

//-----------------------------------------------------------------------------
// 関数名 : ReleaseDraw()
// 機能概要: Direct Draw オブジェクトの削除
//-----------------------------------------------------------------------------
void ReleaseDraw(void)
{
    ・
    ・
    ・

}

[POINT]

  1. myDraw.cppの中でしか使わない変数・関数にはstaticを付ける

(b) WinMain.cppの編集

4-2(a)の変更に伴い、WinMain.cppをさらに修正しなければならない。

  1. ddutil.hはmyDraw.cppでしか使わないため、インクルードをはずす(#include "ddutil.h"を削除する)。
  2. InitFail関数はmyDraw.cppでしか使わないため、プロトタイプ宣言から削除する。
  3. DirectDraw関係のグローバル変数はmyDraw.cppで外部変数として宣言してあるため、次のように修正する。
    //-----------------------------------------------------------------------------
    // 外部変数(本体は別ソース)
    //-----------------------------------------------------------------------------
    /* DirectDrawオブジェクト関係 */
    extern LPDIRECTDRAW7 g_pDD;                // DirectDraw オブジェクト
    extern LPDIRECTDRAWSURFACE7 g_pDDSPrimary; // プライマリ・サーフェイス
    extern LPDIRECTDRAWSURFACE7 g_pDDSBack;    // バック・サーフェイス 
    extern LPDIRECTDRAWSURFACE7 g_pDDSStart;   // スタート画像用サーフェイス
    extern LPDIRECTDRAWSURFACE7 g_pDDSGame;    // ゲーム画像用サーフェイス
    • = NULLが無いことに注意!!
    • g_pDDPal、szStartBmp[]、szGameBmp[] はmyDraw.cppでしか使わないため削除する。

[修正後のWinMain.cpp]

//=============================================================================
//      2Dゲーム基本プログラム2(基本プログラムからの分割)
//=============================================================================
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <ddraw.h>

//-----------------------------------------------------------------------------
// マクロ定義
//-----------------------------------------------------------------------------
#define START_INIT     0
#define START_FRAME    1
#define GAME_INIT      10
#define GAME_FRAME     11

//-----------------------------------------------------------------------------
// プロトタイプ宣言
//-----------------------------------------------------------------------------
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
HWND InitApp(HINSTANCE, int);
HRESULT InitializeDraw(HWND);
void ReleaseDraw(void);
void UpdateFrame(HWND);
void StartInit(HWND);
void StartFrame(HWND);
void GameInit(HWND);
void GameFrame(HWND);
bool HitCheck(RECT, RECT);

//-----------------------------------------------------------------------------
// 外部変数(本体は別ソース)
//-----------------------------------------------------------------------------
/* DirectDrawオブジェクト関係 */
extern LPDIRECTDRAW7 g_pDD;                 // DirectDraw オブジェクト
extern LPDIRECTDRAWSURFACE7 g_pDDSPrimary;  // プライマリ・サーフェイス
extern LPDIRECTDRAWSURFACE7 g_pDDSBack;     // バック・サーフェイス
extern LPDIRECTDRAWSURFACE7 g_pDDSStart;    // スタート画像用サーフェイス
extern LPDIRECTDRAWSURFACE7 g_pDDSGame;     // ゲーム画像用サーフェイス

//-----------------------------------------------------------------------------
// グローバル変数
//-----------------------------------------------------------------------------
/* ウィンドウ関係 */
char szWinName[] = "Skeleton";                  // ウィンドウクラス名
char szTitle[] = "2Dゲーム基本プログラム2";  // ウィンドウタイトル名

/* スタート処理用 */
RECT TitleRect;     // タイトルの矩形
RECT StartRect;     // スタート画像の矩形

/* ゲーム処理用 */
RECT AngelRect;                 // 天使の矩形
int AngelWidth, AngelHeight;    // 天使の幅・高さ
int AngelX, AngelY;             // 天使の表示座標
int AngelMoveX, AngelMoveY;     // 天使の移動量
RECT GokiRect;                  // ゴキブリの矩形
int GokiWidth, GokiHeight;      // ゴキブリの幅・高さ
int GokiX, GokiY;               // ゴキブリの表示座標

/* 共通 */
BYTE g_FrameNo = START_INIT;        // フレーム選択用
BYTE KeyTbl[256];                   // キー情報
RECT ScreenRect = {0, 0, 640, 480}; // ウィンドウの矩形

//=============================================================================
//      ウィンドウメイン関数(WinMain)
//=============================================================================
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
    ・
    ・
    ・

}

//=============================================================================
//      ウィンドウプロシジャ関数(WindowProcedure)
//=============================================================================
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    ・
    ・
    ・

}

//=============================================================================
//  関数名 :InitApp
//  機能概要:表示するウィンドウの定義、登録、表示
//  戻り値 :正常終了のとき1、以上終了のとき0
//=============================================================================
HWND InitApp(HINSTANCE hThisInst, int nWinMode)
{
    ・
    ・
    ・

}

//-----------------------------------------------------------------------------
// 関数名 : UpdateFrame()
// 機能概要: 画面更新処理
//-----------------------------------------------------------------------------
void UpdateFrame(HWND hWnd)
{
    ・
    ・
    ・

}

//-----------------------------------------------------------------------------
// 関数名 : StartInit()
// 機能概要: スタート処理初期化
//-----------------------------------------------------------------------------
void StartInit(HWND hWnd)
{
    ・
    ・
    ・

}

//-----------------------------------------------------------------------------
// 関数名 : StartFrame()
// 機能概要: 画面更新処理
//-----------------------------------------------------------------------------
void StartFrame(HWND hWnd)
{
    ・
    ・
    ・

}

//-----------------------------------------------------------------------------
// 関数名 : GameInit()
// 機能概要: スタート処理初期化
//-----------------------------------------------------------------------------
void GameInit(HWND hWnd)
{
    ・
    ・
    ・

}

//-----------------------------------------------------------------------------
// 関数名 : GameFrame()
// 機能概要: 画面更新処理
//-----------------------------------------------------------------------------
void GameFrame(HWND hWnd)
{
    ・
    ・
    ・

}

//-----------------------------------------------------------------------------
// 関数名 : HitCheck()
// 機能概要: あたり判定関数
//-----------------------------------------------------------------------------
bool HitCheck(RECT Rect1, RECT Rect2)
{
    ・
    ・
    ・

}

[POINT]

  1. 他のソースにある変数を利用する(外部変数の本体が他のソースにある)場合は、externを付けて変数を宣言する。このとき、初期値を設定するとエラーになる。
  2. InitializeDraw関数、ReleaseDraw関数はプロトタイプ宣言はあるが、関数本体はmyDraw.cppにある。

確認!!

ここまでやったらリビルドを行い、プログラムが正常に動くかどうか確かめよう。

(c) myDraw.hの作成

通常、他のソースにある関数を使う場合、使いたい関数をプロトタイプ宣言して使うのではなく、そのソースに存在する関数のプロトタイプ宣言がしてあるヘッダ・ファイルをインクルードして利用する。
3-1でmyDraw.cppを作成し、3-2でプロトタイプ宣言することによりInitializeDrawやReleaseDraw関数を利用しているが、これをヘッダ・ファイルから利用するようにプログラムを修正する。

  1. 「プロジェクト」→「プロジェクトへ追加」→「新規作成」を選択
  2. C/C++ヘッダーファイルを選択し、ファイル名にmyDraw.hと入力し、位置がプロジェクトのフォルダになっていることを確認して、OKボタンをクリック
  3. myDraw.hにmyDraw.cppで作成した関数のうち、他のソースから利用される関数のプロトタイプ宣言を行う
    //-----------------------------------------------------------------------------
    // myDraw.cppの関数のうち、他のソースで利用される関数のプロトタイプ宣言
    //-----------------------------------------------------------------------------
    HRESULT InitializeDraw(HWND);
    void ReleaseDraw(void);
  4. WinMain.cppとmyDraw.cppから上記2つのプロトタイプ宣言を削除する
    [修正後のWinMain.cpp]
    //-----------------------------------------------------------------------------
    // プロトタイプ宣言
    //-----------------------------------------------------------------------------
    LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
    HWND InitApp(HINSTANCE, int);
    void UpdateFrame(HWND);
    void StartInit(HWND);
    void StartFrame(HWND);
    void GameInit(HWND);
    void GameFrame(HWND);
    bool HitCheck(RECT, RECT);
    [修正後のmyDraw.cpp]
    //-----------------------------------------------------------------------------
    // プロトタイプ宣言
    //-----------------------------------------------------------------------------
    static HRESULT InitFail(HWND, HRESULT, LPCTSTR, ...); 
    
  5. WinMain.cppとmyDraw.cppでmyDraw.hをインクルードする
    #include "myDraw.h"

確認!!

ここまでやったらリビルドを行い、プログラムが正常に動くかどうか確かめよう。


[ TOP ]