Program

WindowsのWinMain?をクラスの中に隠蔽して纏め上げる

  • WinMain?をクラスにまとめて使用する方法をまとめてみました。
    あくまで一例でこれが正しいというわけではありません。
    もちろんクラスにまとめずにそのまま記述することも可能です。

  • 気をつける点としてはWinMain?そのものを記述しているわけではないことです。
    WinMain?関数はWindowsProgram?では基本的に自動的に最初に呼ばれるため、WinMain?関数そのものをクラス化することはできません。
    そのため、WinMain?そのものは「winmain.cpp」で宣言して、その中でWinMain?クラスを呼び出して使用するようになっています。

  • 途中までWindow自体のクラス化をもくろんで生成してたので余分なvirtualが書かれていますが、気にしないでください。
    そのうち修正予定です。

  • WinMain?の入り口と本体クラスを実体化して、必要な変数を渡す C:\work\private\directx\directx\winmain.cpp
    ////////////////////////////////////////////////////////////////////////////////
    // Winmain.cpp
    //
    // Windowsのメイン関数処理のみ
    //
    ////////////////////////////////////////////////////////////////////////////////
    
    // WinXP以降にターゲット
    #ifndef WINVER
    #define WINVER         0x0501
    #endif
    #ifndef _WIN32_WINDOWS
    #define _WIN32_WINDOWS 0x0501 
    #endif
    #ifndef _WIN32_WINNT
    #define _WIN32_WINNT   0x0600 
    #endif
    
    #define WIN32_LEAN_AND_MEAN    // Windows ヘッダーから使用されていない部分を除外します。
    
    #define _WIN32_DCOM        //DCOM使用宣言
    
    #include <windows.h>
    #include <stdio.h>	    //標準
    #include <stdlib.h>
    #include <tchar.h>
    #include <locale.h>
    
    #include "cwinmain.h"
    
    // デバッグ用呪文
    #if _DEBUG
    #define _CRTDBG_MAP_ALLOC
    #include <crtdbg.h>
    #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
    #endif
    
    // CWinMainを継承したクラス
    ///////////////////////////////////////////////////////////////
    // Winmain関数
    ///////////////////////////////////////////////////////////////
    int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    {
        int    ret = 0;
    
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
    
        #ifdef _DEBUG 
            // メモリリーク監視
            _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
        #endif
    
            // 解像度を指定して初期化
        WINMAIN::CWinMain *cWinMain = new WINMAIN::CWinMain(800, 600);
    
        // 初期設定
        // 外部ファイル、またはコマンドラインから設定を読み込んで設定するべき
        cWinMain->g_lpctAPP_NAME = _T("Window Sample Debugテスト");
        cWinMain->g_lpctPROP_NAME = _T("WinMainProp");
        cWinMain->g_lpctAPP_CLASSNAME = _T("WinMainClass");
    
        cWinMain->_tCWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
    
        if(cWinMain != NULL)
        {
            delete cWinMain;
        }
    
        return ret;
    }
    

  • クラスのヘッダー C:\work\private\directx\directx\CWinmain.h
    ////////////////////////////////////////////////////////////////////////////////
    // CWinmain.h
    //
    // Windowsのメイン関数処理用ヘッダー
    //
    ////////////////////////////////////////////////////////////////////////////////
    //二重インクルード防止用定義
    #ifndef CWinmain_H
    #define CWinmain_H
    
    #include <string>
    
    #include "gamemain.h"
    #include "cerrcode.h"
    #include "cdx9base.h"
    
    // Mainのネームスペース
    namespace WINMAIN
    {
        class CWinMain
        {
    
        private:
            ////////////////////////////////////////////////////////////////////////////////
            //    ローカル変数
            ////////////////////////////////////////////////////////////////////////////////
            int    m_ioldDtW;        // デスクトップのサイズ 幅
            int    m_ioldDtH;        // デスクトップのサイズ 高さ
    
            HINSTANCE m_hInst;        // インスタンス
            HINSTANCE m_hPrevInst;    // プライベートインスタンス
            LPTSTR m_lpsCmdLine;        // コマンドラインからの文字
            int m_nCmdShow;            // 表示状態
    
            // 2重起動防止変数
            HANDLE    m_hMutex;        // ミューテックスのハンドル
            // クリティカルセッション制御変数
            CRITICAL_SECTION m_cs;
            
            //Windowの生成変数
            HWND m_hWndMain;        // Windowのハンドル
    
            // Windowのサイズ関係
            POINT m_pSize;            // Windowのサイズ(全部込み)
            POINT m_pPos;            // Windowの位置
            
            // Window判別用のProcName
            static LPCTSTR m_lpctPROP_NAME;//    "WinMainProp"
    
            // WindClassのATOM
            ATOM    m_aRegClassATOM;
    
            CGamemain *m_GameMain;    // ゲームメイン
    
            ////////////////////////////////////////////////////////////////////////////////
            //    ローカル関数
            ////////////////////////////////////////////////////////////////////////////////
            ////////////////////////////////////////////////////////////////////////
            //  ウィンドウ クラスを登録
            // 渡し値:HINSTANCE hInstance    // インスタンス
            ////////////////////////////////////////////////////////////////////////
            ATOM MyRegisterClass(HINSTANCE hInstance);
    
            ////////////////////////////////////////////////////////////////////////
            // Windowの生成
            ////////////////////////////////////////////////////////////////////////
            bool InitWindow(DWORD dwExStyle, DWORD dwStyle);
    
            ////////////////////////////////////////////////////////////////////////
            // 2重起動確認
            // MUTEX を利用
            ////////////////////////////////////////////////////////////////////////
            int IsRunningApplication(LPCTSTR lpcszApp, HANDLE *pHandle);
    
            ////////////////////////////////////////////////////////////////////////
            // ウィンドウハンドルをm_hWndMainから切り離す
            ////////////////////////////////////////////////////////////////////////
            bool Detach(void);
    
            ////////////////////////////////////////////////////////////////////////
            // フレームとキャプションを含んだWindowのサイズを返す
            ////////////////////////////////////////////////////////////////////////
            POINT GetStartWindowSize(const HWND hWnd, const int iX, const int iY);
    
            ////////////////////////////////////////////////////////////////////////
            // 中央位置を返す
            // 背後対象となるWindowのハンドル
            ////////////////////////////////////////////////////////////////////////
            POINT GetCenterPosition(const HWND hWnd, const POINT pSize);
    
            ////////////////////////////////////////////////////////////////////////
            // ウインドウサイズを設定
            ////////////////////////////////////////////////////////////////////////
            void SetClientWindowSize(const HWND hWnd, const POINT pSize, const int iLeft, const int iTopl);
    
        protected: //派生先からのみ呼び出し可能なコンストラクタ
    
        public:
    
            ////////////////////////////////////////////////////////////////////////////////
            //    クラスの初期化
            //    コンストラクタ
            ////////////////////////////////////////////////////////////////////////////////
            CWinMain(int iWidth, int iHeight);
    
            ////////////////////////////////////////////////////////////////////////////////
            //    クラスの後始末
            //    デストラクタ
            //    2重開放されない用にする
            ////////////////////////////////////////////////////////////////////////////////
            ~CWinMain();
    
            ////////////////////////////////////////////////////////////////////////////////
            //    グローバル定数
            ////////////////////////////////////////////////////////////////////////////////
            #define g_dWindStyleStandard        WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX // キャプションや縁付
            #define g_dWindStyleSimple            WS_POPUP                            // 何もなし
    
    
            ////////////////////////////////////////////////////////////////////////////////
            //    グローバル変数
            ////////////////////////////////////////////////////////////////////////////////
            int    g_iWindX;                // Windowの表示左上
            int    g_iWindY;                // Windowの表示左上
    
            int g_dWindWidth;            // 作成するWindowの幅
            int g_dWindHeight;            // 作成するWindowの高さ
    
            LPCTSTR g_lpctAPP_NAME;// "Window Sample Debug"
            //ウィンドウクラスの名前
            LPCTSTR g_lpctAPP_CLASSNAME;//    "WinMainClass"
            //ウィンドウにthisポインタ関連付ける時のプロパティ名
            LPCTSTR g_lpctPROP_NAME;//    "WinMainProp"
    
            ///////////////////////////////////////////////////////////////
            // グローバル関数
            ///////////////////////////////////////////////////////////////
    
            ///////////////////////////////////////////////////////////////
            // Winmain関数
            ///////////////////////////////////////////////////////////////
            virtual int APIENTRY _tCWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow);
    
            ///////////////////////////////////////////////////////////////
            // クラスで唯一のウィンドウプロシージャ
            ///////////////////////////////////////////////////////////////
            static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
            ///////////////////////////////////////////////////////////////
            // オーバーロード可能なWinmainメッセージループ
            ///////////////////////////////////////////////////////////////
            virtual LRESULT WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
            ///////////////////////////////////////////////////////////////
            //メンバを参照するためのインターフェース
            ///////////////////////////////////////////////////////////////
            // メインウィンドウのHWNDを返す
            ///////////////////////////////////////////////////////////////
            HWND GetCurrentHwnd(void);
    
            ///////////////////////////////////////////////////////////////
            // メインウィンドウのHINSTANCEを返す
            ///////////////////////////////////////////////////////////////
            HINSTANCE GetCurrentInstance(void);
    
            ///////////////////////////////////////////////////////////////
            // メインウィンドウのPreviousInstanceを返す
            // 基本的にNULLのはず
            ///////////////////////////////////////////////////////////////
            HINSTANCE GetPreviousInstance(void);
    
            ///////////////////////////////////////////////////////////////
            // メインウィンドウに渡されたコマンドラインを返す
            ///////////////////////////////////////////////////////////////
            LPTSTR GetCmdLine(void);
    
            ///////////////////////////////////////////////////////////////
            // メインウィンドウに渡された初期表示状態を返す
            ///////////////////////////////////////////////////////////////
            int GetnCmdShow(void);
    
        };
    
    };
    
    #endif CWinmain_H

  • クラスの本体
  • 「CALLBACK WndProc?」は「static」で宣言しているため、クラスのポインタを渡さなければなりません。
    そこで、「SetProp?」「GetProp?」「RemoveProp?」といったものを利用して、クラスのポインタを受け渡ししています。
    C:\work\private\directx\directx\CWinmain.cpp
    ////////////////////////////////////////////////////////////////////////////////
    // CWinmain.cpp
    //
    // Windowsのメイン関数処理用本体
    //
    ////////////////////////////////////////////////////////////////////////////////
    /*
     メモエリア
      ・根本的に継承クラスにして、純粋仮想関数でループを実装しておいたほうが汎用性があるか?
    
      ・実際に使用するWindowは別で精製?
       仮想フルスクリーンでの手間軽減
    
      ・Window変更用コード
       ・枠の表示、非表示
            GetWindowLong、SetWindowLong を使うとウィンドウスタイルの取得・変更が出来ます
    
      ・フルスクリーンの切り替え
        解像度込みの変更と仮想フルスクリーン両方に対応させる
        Alt+Enter フルスクリーン Ctrl+Enter 仮想フルスクリーン
      ・色数の切り替え
       いるのか?
    
      ・メニューバーの制御
       枠関係のコードに関係してくるが、サブクラスとしてメニューを別ウィンドウに持たすか?
    
       ・アイコンの設定
        LoadImage 
        HANDLE LoadImage(
    HINSTANCE hinst,   // インスタンスのハンドル
    LPCTSTR lpszName,  // イメージの名前または識別子
    UINT uType,        // イメージのタイプ
    int cxDesired,     // 希望する幅
    int cyDesired,     // 希望する高さ
    UINT fuLoad        // ロードのオプション
    );
    
    uType
    IMAGE_BITMAP     ビットマップをロードします。
    IMAGE_CURSOR     カーソルをロードします。
    IMAGE_ICON     アイコンをロードします。
    
    fuLoad
    LR_LOADFROMFILE     lpszName パラメータで指定するファイルからイメージをロードします。このフラグを指定しないと、lpszName はりソースの名前として認識されます。
    
    
    */
    
    // WinXP以降にターゲット
    #ifndef WINVER
    #define WINVER         0x0501
    #endif
    #ifndef _WIN32_WINDOWS
    #define _WIN32_WINDOWS 0x0501 
    #endif
    #ifndef _WIN32_WINNT
    #define _WIN32_WINNT   0x0600 
    #endif
    
    #define WIN32_LEAN_AND_MEAN    // Windows ヘッダーから使用されていない部分を除外します。
    
    #pragma comment(lib, "winmm.lib")
    
    #include <windows.h>
    
    #include <stdio.h>	    //標準
    #include <stdlib.h>
    
    #include "cwinmain.h"
    
    
    // デバッグ用呪文
    #if _DEBUG
    #define _CRTDBG_MAP_ALLOC
    #include <crtdbg.h>
    #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
    #endif
    
    namespace WINMAIN
    {
        LPCTSTR    CWinMain::m_lpctPROP_NAME = _T("default");
    
        ///////////////////////////////////////////////////////////////
        // Winmain関数
        ///////////////////////////////////////////////////////////////
        int APIENTRY CWinMain::_tCWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
        {
            MSG msg;
            int ret = 0;
            //プログラム本体のWinMain関数から引数を受け取り、メンバ変数へ代入。
            m_hInst            =    hInstance;
            m_hPrevInst        =    hPrevInstance;
            m_lpsCmdLine    =    lpCmdLine;
            m_nCmdShow        =    nCmdShow;
    
            ////////////////////////////////////////////////////////////////
            // 2重起動の確認をミューテックスを利用して確認する
            ////////////////////////////////////////////////////////////////
            ret = IsRunningApplication( g_lpctAPP_NAME, &m_hMutex );
            if(ret == 1 || ret == 2)
            {
                //起動済み    終了
                return -1;
            }
    
            m_lpctPROP_NAME = g_lpctPROP_NAME;
    
    
            // ウインドクラスの登録
            m_aRegClassATOM = MyRegisterClass(m_hPrevInst);
    
            // Windowの生成
            if(!InitWindow(0, g_dWindStyleStandard))
    //        if(!InitWindow(0, g_dWindStyleSimple))
            {
                return -1;
            }
    
            // クリティカルセッションの初期化
    //        InitializeCriticalSection(&m_cs);
    
            //    メッセージループ
            while(true)
            {
                if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                {
                    if (WM_QUIT == msg.message)
                    {
                        break;
                    }
                    TranslateMessage(&msg); 
                    DispatchMessage(&msg);
                }
    
                Sleep(1);
            }
    
            // クリティカルセッションの終了
    //        LeaveCriticalSection(&m_cs);
    
            // ウィンドクラスを削除
            UnregisterClass(g_lpctAPP_CLASSNAME, m_hInst);
    
            return (int)msg.wParam;
        }
    
        ///////////////////////////////////////////////////////////////
        // クラスで唯一のウィンドウプロシージャ
        ///////////////////////////////////////////////////////////////
        LRESULT CWinMain::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        {
            // WM_CREATE はSetProcより前に発生するのでそれに対処
            if(WM_CREATE == uMsg)
            {
    //            CWinMain* pStatic = (CWinMain*)GetProp(hWnd, ((LPCTSTR)((CREATESTRUCT *)lParam)->lpCreateParams));
                CWinMain* pStatic = (CWinMain*)(((CREATESTRUCT *)lParam)->lpCreateParams);
                if(pStatic != NULL)
                {
                    return pStatic->WindowProc(hWnd, uMsg, wParam, lParam);    
                }
                else
                {
                    return DefWindowProc(hWnd, uMsg, wParam, lParam);
                }
            }
            else
            {
                LRESULT lret;
    
                CWinMain *pTargetWnd = (CWinMain*)GetProp(hWnd, m_lpctPROP_NAME);
    
                if(pTargetWnd==NULL)
                {
                    return DefWindowProc(hWnd, uMsg, wParam, lParam);
                }
    
                //ウィンドウプロシージャ本体を呼び出す
                lret = pTargetWnd->WindowProc(hWnd, uMsg, wParam, lParam);    
                if(uMsg == WM_NCDESTROY)
                {
                    pTargetWnd->Detach();
                }
                return lret;
            }
    
        }
    
        ///////////////////////////////////////////////////////////////
        // オーバーロード可能なWinmainメッセージループ
        ///////////////////////////////////////////////////////////////
        LRESULT CWinMain::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        {
            switch(uMsg)
            {
            case WM_CREATE:
                {
                    PostMessage(hWnd, WM_APP + 1000, (WPARAM)NULL,(LPARAM) NULL);
                }
            break;
    
            case WM_SHOWWINDOW:
                {
                }
            break;
    
            case WM_APP + 1000:
                {
                    // 本来のサイズに設定
                    m_pSize = GetStartWindowSize(m_hWndMain, g_dWindWidth, g_dWindHeight);
                    m_pPos = GetCenterPosition(GetDesktopWindow(), m_pSize);
                    SetClientWindowSize(m_hWndMain, m_pSize, m_pPos.x, m_pPos.y);
    
                    // ゲームメインを生成
                    m_GameMain = new CGamemain(m_hWndMain);
    
                }
            break;
    
            case WM_MOVE:
                {
                }
            break;
    
            case WM_LBUTTONDOWN:
                {
                }
            break;
    
            case WM_SYSKEYDOWN:
                {
                    if(wParam == VK_MENU)
                    {
                        if( GetKeyState( VK_RETURN ) & 0x80 )  // Altキーが押されているか
                        {
                            break;
                        }
                        else
                        {
                            DefWindowProc(hWnd, uMsg, wParam, lParam);
                        }
                    }
                    else
                    if(wParam == VK_RETURN)
                    {
                        if( GetKeyState( VK_MENU ) & 0x80 )  // Altキーが押されているか
                        {
                            break;
                        }
                        else
                        {
                            DefWindowProc(hWnd, uMsg, wParam, lParam);
                        }
                    }
                    else
                    if(wParam == VK_CONTROL)
                    {
                        if( GetKeyState( VK_RETURN ) & 0x80 )  // Ctrlキーが押されているか
                        {
                            break;
                        }
                        else
                        {
                            DefWindowProc(hWnd, uMsg, wParam, lParam);
                        }
                    }
                    else
                    if(wParam == VK_RETURN)
                    {
                        if( GetKeyState( VK_CONTROL ) & 0x80 )  // Ctrlキーが押されているか
                        {
                            break;
                        }
                        else
                        {
                            DefWindowProc(hWnd, uMsg, wParam, lParam);
                        }
                    }
                    else
                    {
                        DefWindowProc(hWnd, uMsg, wParam, lParam);
                    }
                }
                break;
    
            case WM_KEYDOWN:
                {
                }
                break;
    
            // Windowsの終了を取得
            case WM_QUERYENDSESSION:
                // WIndowsの終了を拒否
                return true;
    
            // WM_QUERYENDSESSIONの後発生
            case WM_ENDSESSION:
                // falseなら終了は拒否されている
                if(wParam == false)
                {
                }
                else
                {
                    // プログラムを終了させる
                    DestroyWindow(hWnd);
                }
                break;
    
            case WM_CLOSE:
                DestroyWindow(hWnd);
                break;
    
            case WM_DESTROY:
                {
                    PostQuitMessage(0);
                }
                break;
    
            case WM_PARENTNOTIFY:
                {
                }
                break;
    
            default:
                return (DefWindowProc(hWnd, uMsg, wParam, lParam));
            }
    
            return 0;
        }
    
        ////////////////////////////////////////////////////////////////////////
        //  ウィンドウ クラスを登録
        // 渡し値:HINSTANCE hInstance    // インスタンス
        ////////////////////////////////////////////////////////////////////////
        ATOM CWinMain::MyRegisterClass(HINSTANCE hInstance)
        {
            WNDCLASSEX wcex;        // 
    
            wcex.cbSize            = sizeof(WNDCLASSEX);
            wcex.style            = CS_HREDRAW | CS_VREDRAW;
            wcex.lpfnWndProc        = (WNDPROC)CWinMain::WndProc;
            wcex.cbClsExtra        = 0; 
            wcex.cbWndExtra        = 0; 
            wcex.hInstance        = hInstance; 
            wcex.hIcon            = NULL;
            wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
            wcex.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH); 
            wcex.lpszMenuName        = NULL;
            wcex.lpszClassName    = g_lpctAPP_CLASSNAME;
            wcex.hIconSm            = NULL;
    
            return RegisterClassEx(&wcex);
        }
    
        ////////////////////////////////////////////////////////////////////////
        // Windowの生成
        // 渡し値:DWORD dwExStyle    // 拡張スタイル
        //         DWORD dwStyle    // 標準スタイル
        ////////////////////////////////////////////////////////////////////////
        bool CWinMain::InitWindow(DWORD dwExStyle, DWORD dwStyle)
        {
            
            //    実際のWindを作成
            // WM_CREATEはこれの時点で発生するため、対処のためにThisポインタを渡しておく
            m_hWndMain = CreateWindowEx(
                                dwExStyle,
                                g_lpctAPP_CLASSNAME,
                                g_lpctAPP_NAME,
                                dwStyle,
                                0,
                                0,
                                CW_USEDEFAULT,
                                CW_USEDEFAULT,
                                NULL,
                                NULL, 
                                m_hInst,
                                (LPVOID)this); 
    
            //    作成成功の有無
            if (!m_hWndMain)
            {
                return false;
            }
    
            //cWinmainポインタをウィンドウに関連付ける
            if(!SetProp(m_hWndMain, m_lpctPROP_NAME, (HANDLE)this))
            {
                return false;
            }
    
            //    Windを表示状態で表示する
            ShowWindow(m_hWndMain, m_nCmdShow); 
            UpdateWindow(m_hWndMain); 
    
            return true;
        }
    
        ////////////////////////////////////////////////////////////////////////
        // 2重起動確認
        // MUTEX を利用
        ////////////////////////////////////////////////////////////////////////
        int CWinMain::IsRunningApplication(LPCTSTR lpcszApp, HANDLE *pHandle)
        {
            int ret = 0;
            OSVERSIONINFO inf;
            char cTemp[MAX_PATH];
    
            ////////////////////////////////////////////////////////////////////////
            //初期化
            ////////////////////////////////////////////////////////////////////////
            ZeroMemory(&inf,sizeof(OSVERSIONINFO));
            *pHandle = NULL;
            inf.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    
            ////////////////////////////////////////////////////////////////////////
            //Windows2000以上から全ユーザ対象にイベントオブジェクトを検索可能となって
            //いるので、現在のOSをチェックし、実際のイベントオブジェクト名を作成する
            ////////////////////////////////////////////////////////////////////////
            if(GetVersionEx(&inf))
            {
                if((inf.dwPlatformId == VER_PLATFORM_WIN32_NT) && (inf.dwMajorVersion >= 5))
                {
                    sprintf_s(cTemp, sizeof(cTemp),"Global\\%s",lpcszApp);
                }
            }
            ////////////////////////////////////////////////////////////////////////
            //アプリケーションが起動しているかチェックする
            ////////////////////////////////////////////////////////////////////////
            if((*pHandle=CreateMutex(NULL, true, (LPCTSTR)cTemp))!=NULL)
            {
                ////////////////////////////////////////////////////////////////////////
                //既に起動されている場合
                ////////////////////////////////////////////////////////////////////////
                if(GetLastError()==ERROR_ALREADY_EXISTS)
                {
                    CloseHandle(*pHandle);
                    *pHandle=NULL;
                    ret=1;
    //                cError->PrintErrStr(TEXT("CWinMain::IsRunningApplication"),TEXT("2重起動のエラー"),TEXT("該当するアプリケーションは、既に起動しています。"));
                }
            }
            else
            {
                ////////////////////////////////////////////////////////////////////////
                //他のユーザ上で起動している場合
                ////////////////////////////////////////////////////////////////////////
                ret=2;
    //            cError->PrintErrStr(TEXT("CWinMain::IsRunningApplication"),TEXT("2重起動のエラー"),TEXT("該当するアプリケーションは、他のユーザーが起動しています。"));
            }
            return(ret);
        }
    
        ////////////////////////////////////////////////////////////////////////
        // フレームとキャプションを含んだWindowのサイズを返す
        ////////////////////////////////////////////////////////////////////////
        POINT CWinMain::GetStartWindowSize(const HWND hWnd,const int iX, const int iY)
        {
            RECT wRect, cRect;
            int wX,wY,cX,cY;
            POINT pSize;
    
            GetWindowRect(hWnd, &wRect);
            GetClientRect(hWnd, &cRect);
    
            // Windowの大きさを取得
            wX = wRect.left + wRect.right;
            wY = wRect.top + wRect.bottom;
            // クライアント領域の大きさをWindowの大きさから引いてフレームをキャプションのサイズを出す
            cX = wX - cRect.right;
            cY = wY - cRect.bottom;
    
            pSize.x = cX + iX;
            pSize.y = cY + iY;
    
            return pSize;
    
        }
    
        ////////////////////////////////////////////////////////////////////////
        // 中央位置を返す
        // 背後対象となるWindowのハンドル
        ////////////////////////////////////////////////////////////////////////
        POINT CWinMain::GetCenterPosition(const HWND hWnd, const POINT pSize)
        {
            POINT Pos;
            RECT wRect;
    
            GetWindowRect(hWnd, &wRect);
            Pos.x = (wRect.right - pSize.x) / 2;
            Pos.y = (wRect.bottom - pSize.y) / 2;
    
            return Pos;
        }
    
        ////////////////////////////////////////////////////////////////////////
        // 表示位置とウインドウサイズを設定し表示
        ////////////////////////////////////////////////////////////////////////
        void CWinMain::SetClientWindowSize(const HWND hWnd, const POINT pSize, const int iLeft, const int iTop)
        {
            SetWindowPos(hWnd, HWND_TOP, iLeft, iTop, pSize.x, pSize.y, SWP_SHOWWINDOW);
        }
    
        ///////////////////////////////////////////////////////////////
        //メンバを参照するためのインターフェース
        ///////////////////////////////////////////////////////////////
        // メインウィンドウのHWNDを返す
        ///////////////////////////////////////////////////////////////
        HWND CWinMain::GetCurrentHwnd(void)
        {
            return m_hWndMain;
        }
    
        ///////////////////////////////////////////////////////////////
        // メインウィンドウのHINSTANCEを返す
        ///////////////////////////////////////////////////////////////
        HINSTANCE CWinMain::GetCurrentInstance(void)
        {
            return m_hInst;
        }
    
        ///////////////////////////////////////////////////////////////
        // メインウィンドウのPreviousInstanceを返す
        // 基本的にNULLのはず
        ///////////////////////////////////////////////////////////////
        HINSTANCE CWinMain::GetPreviousInstance(void)
        {
            return m_hPrevInst;
        }
    
        ///////////////////////////////////////////////////////////////
        // メインウィンドウに渡されたコマンドラインを返す
        ///////////////////////////////////////////////////////////////
        LPTSTR CWinMain::GetCmdLine(void)
        {
            return m_lpsCmdLine;
        }
    
        ///////////////////////////////////////////////////////////////
        // メインウィンドウに渡された初期表示状態を返す
        ///////////////////////////////////////////////////////////////
        int CWinMain::GetnCmdShow(void)
        {
            return m_nCmdShow;
        }
    
        ////////////////////////////////////////////////////////////////////////
        // ウィンドウハンドルをm_hWndMainから切り離す
        ////////////////////////////////////////////////////////////////////////
        bool CWinMain::Detach(void)
        {
            if(m_hWndMain == NULL)
            {
                return false;
            }
    
            if(GetProp(m_hWndMain, m_lpctPROP_NAME))
            {
                RemoveProp(m_hWndMain, m_lpctPROP_NAME);
            }
            return true;
        }
    
        ////////////////////////////////////////////////////////////////////////////////
        //    クラスの初期化
        //    コンストラクタ
        ////////////////////////////////////////////////////////////////////////////////
        CWinMain::CWinMain(int iWidth, int iHeight)
        {
            // パラメーターを初期化
            g_dWindWidth = iWidth;
            g_dWindHeight = iHeight;
    
            //    デスクトップのサイズを取得
            m_ioldDtW = GetSystemMetrics(SM_CXSCREEN);
            m_ioldDtH = GetSystemMetrics(SM_CYSCREEN);
    
            m_hInst = NULL;
            m_hPrevInst = NULL;
            m_lpsCmdLine = NULL;
            m_nCmdShow = SW_SHOW;
    
            m_hWndMain = NULL;
    
            m_hMutex = NULL;
    
            m_GameMain = NULL;
    
        }
    
        ////////////////////////////////////////////////////////////////////////////////
        //    クラスの後処理
        //    デストラクタ
        ////////////////////////////////////////////////////////////////////////////////
        CWinMain::~CWinMain()
        {
            if(m_GameMain != NULL)
            {
                delete(m_GameMain);
            }
    
            this->Detach();
    
            // ミューテックスの解除
            if(m_hMutex != NULL)
            {
                ReleaseMutex(m_hMutex);
            }
        }
    
    };

  • 派生元の基幹クラスのヘッダー
    ////////////////////////////////////////////////////////////////////////////////
    // CGMain.cpp
    //
    // 基幹
    //
    ////////////////////////////////////////////////////////////////////////////////
    #include "CGmain.h"
    
    namespace GMain
    {
        ////////////////////////////////////////////////////////////////////////////////
        // クラスの初期化
        // コンストラクタ
        ////////////////////////////////////////////////////////////////////////////////
        CGMain::CGMain(void)
        {
        }
    
        ////////////////////////////////////////////////////////////////////////////////
        // クラスの後始末
        // デストラクタ
        ////////////////////////////////////////////////////////////////////////////////
        CGMain::~CGMain()
        {
        }
    
    };
    

  • 派生元の基幹クラスの本体
    ////////////////////////////////////////////////////////////////////////////////
    // CGMain.cpp
    //
    // 基幹
    //
    ////////////////////////////////////////////////////////////////////////////////
    #include "CGmain.h"
    
    namespace GMain
    {
        ////////////////////////////////////////////////////////////////////////////////
        // クラスの初期化
        // コンストラクタ
        ////////////////////////////////////////////////////////////////////////////////
        CGMain::CGMain(void)
        {
        }
    
        ////////////////////////////////////////////////////////////////////////////////
        // クラスの後始末
        // デストラクタ
        ////////////////////////////////////////////////////////////////////////////////
        CGMain::~CGMain()
        {
        }
    
    };