Wondow Mode の切替

SetWindowLong で Window Mode と Full Screen Mode を "W" キーで切り替えます。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. 新規作成で空のプロジェクト(Change)を作成してプログラムファイルとヘッダファイルをプロジェクトに追加して下さい。
    myd3d.h と myd3d.cpp は Object Class Library から取得して下さい。
    ファイル名 ファイルの説明
    Change.cpp 「プログラムの説明」を参考に作成して下さい
    myd3d.h MyD3D Object Class ヘッダファイル
    myd3d.cpp MyD3D Object Class プログラムファイル
  2. #define と #include と Global Area の定義です。
    g_bWindow がモードの切り替えフラグで g_D3DPP が現在動作中のモードです。
    g_Wrect にウインドウ・モードの画面サイズを記憶します。
        #include    "MyD3D.h"
    
        // Global Area
        HINSTANCE               g_hInst     = NULL;     // インスタンス・ハンドル
        HWND                    g_hWnd      = NULL;     // ウインドウ・ハンドル
        MyD3D                   *myd3d      = NULL;     // MyD3D Object Class
        LPDIRECT3DDEVICE9       g_pDEV      = NULL;     // Direct3DDeviceインターフェイス
        LPD3DXSPRITE            g_pSprite   = NULL;     // スプライト
        LPDIRECT3DTEXTURE9      g_pTexture  = NULL;     // スプライトに使うテクスチャ
        HMENU                   g_hMenu     = NULL;     // メニュー・ハンドル
        D3DPRESENT_PARAMETERS   g_D3DPP;                // D3DDeviceの設定(現在)
        bool                    g_bActive   = false;    // アクティブ状態
    
        // 描画領域サイズ
        bool        g_bWindow   = true;                 // 起動時の画面モード
        RECT        g_Wrect;                            // ウインドウ・モードの描画領域
        char        g_ImgFile[] = "c:\\data\\test\\emiko.jpg";
        
  3. ウインドウを生成して DirectX Graphics を初期化します。
    最初は Wondow Mode で設定しています。
        int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nCmdShow)
        {   MSG         msg;
            HRESULT     hr;
                :
                :
            // DirectX Graphicsの初期化
            hr = InitDXGraphics();
            if (FAILED(hr))
            {   DXTRACE_ERR("WinMain InitDXGraphics", hr);
                UnregisterClass(NAME, g_hInst);
                return FALSE;
            }
            // ウインドウ表示
            ShowWindow(g_hWnd, SW_SHOWNORMAL);
            UpdateWindow(g_hWnd);
            // メッセージ・ループ
                :
                :
        
  4. DirectX Graphics のインターフェースを取得して Sprite を設定する関数です。
    myd3d->SetD3DPPFull() で Full Screen Mode のパラメータを g_D3DPP に格納します。
    次に myd3d->InitD3D(&g_pDEV) で Window Mode で Direct 3D Device を設定します。
    デバイスが取得できたらスプライトを初期化して画像を入力します。
        HRESULT InitDXGraphics(void)
        {   HRESULT hr;
    
            myd3d= new MyD3D(g_hWnd);
            myd3d->SetD3DPPFull();
            g_D3DPP= myd3d->D3DPPFull;
            myd3d->InitD3D(&g_pDEV);
            // スプライト機能の初期化
            hr = D3DXCreateSprite(g_pDEV, &g_pSprite);
            if (FAILED(hr))     return DXTRACE_ERR("InitDXGraphics D3DXCreateSprite", hr);
            g_pTexture= myd3d->LoadTexture(g_ImgFile);
            return S_OK;
        }
        
  5. Sprite をレンダリングする関数 Render() です。
        HRESULT Render(void)
        {
            if (!g_pDEV || !g_bActive)  return false;
            // シーンのクリア
            g_pDEV->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
            // シーンの描画開始
            if (SUCCEEDED(g_pDEV->BeginScene()))
            {   // シーンの描画(スプライトの描画)
                g_pSprite->Begin(0);
                g_pSprite->Draw(g_pTexture, NULL, NULL, NULL, D3DCOLOR_ARGB(0,255,255,255));
                g_pSprite->End();
                // シーンの描画終了
                g_pDEV->EndScene();
            }
            return g_pDEV->Present(NULL, NULL, NULL, NULL);
        }
        
  6. CALLBACK 関数です。
    WM_SETCURSOR: で Full Screen Mode のときマウスカーソルを非表示にします。
    "W" キーが押されたとき ChangeDisplayMode() で表示モードを切り替えます。
        LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam)
        {   HRESULT hr = S_OK;
    
            switch(msg)
            {   case WM_ACTIVATE:
                    g_bActive = (LOWORD(wParam) != 0);
                    break;
                case WM_SIZE:           // ウインドウ・サイズの変更処理
                    if (g_D3DPP.Windowed != TRUE)   break;
                    if (!g_pDEV || wParam == SIZE_MINIMIZED)  break;
                    g_D3DPP.BackBufferWidth  = LOWORD(lParam);
                    g_D3DPP.BackBufferHeight = HIWORD(lParam);
                    if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED)
                        ChangeWindowSize();
                    break;
                case WM_SETCURSOR:
                    if (g_bWindow != TRUE)
                    {   SetCursor(NULL);
                        return 1;
                    }
                    break;
                case WM_KEYDOWN:
                    switch(wParam)
                    {   case VK_ESCAPE: // [ESCAPE]キーでウインドウを閉じる
                            PostMessage(hWnd, WM_CLOSE, 0, 0);
                            break;
                        case 'W':       // 画面モードの切り替え
                            ChangeDisplayMode();
                            break;
                    }
                    break;
                case WM_DESTROY:
                    if (g_pSprite)  g_pSprite->OnLostDevice();
                    CleanupDXGraphics();
                    PostQuitMessage(0);
                    g_hWnd = NULL;
                    return 0;
            }
            return DefWindowProc(hWnd, msg, wParam, lParam);
        }
        
  7. 画面モードの変更です。
    g_bWindow = !g_bWindow; でモードのフラグを反転します。
    ウインドウ・モードのとき、現在の表示位置を g_Wrect に保存します。
    g_pDEV->Reset(&g_D3DPP) でデバイスをリセットして切り替えます。
    ウインドウ・モードのときはメニューを設定します。
        void  ChangeDisplayMode(void)
        {   HRESULT hr;
    
            g_bWindow = !g_bWindow;
            if (g_pSprite)  g_pSprite->OnLostDevice();
            if (g_bWindow)  hr= g_pDEV->Reset(&(myd3d->D3DPPWin));
            else
            {   GetWindowRect(g_hWnd,&g_Wrect);
                hr= g_pDEV->Reset(&(myd3d->D3DPPFull));
            }
            if (FAILED(hr))
            {
                DXTRACE_ERR("ChangeDisplayMode Reset", hr);
                return;
            }
    
            hr = InitD3DObject();
            if (FAILED(hr))
            {   DXTRACE_ERR("ChangeDisplayMode InitD3DObject", hr);
                DestroyWindow(g_hWnd);
                return;
            }
    
            if (g_bWindow)
            {   SetWindowLong(g_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
                if (g_hMenu != NULL)
                {   SetMenu(g_hWnd, g_hMenu);
                    g_hMenu = NULL;
                }
                SetWindowPos(g_hWnd, HWND_NOTOPMOST,
                        g_Wrect.left, g_Wrect.top,
                        g_Wrect.right - g_Wrect.left,
                        g_Wrect.bottom - g_Wrect.top,
                        SWP_SHOWWINDOW);
            }
            else
            {   SetWindowLong(g_hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
                if (g_hMenu == NULL)
                {   g_hMenu = GetMenu(g_hWnd);
                    SetMenu(g_hWnd, NULL);
                }
            }
        }
        
  8. Sprite の Device を Reset する関数です。
        HRESULT InitD3DObject(void)
        {   HRESULT hr= S_FALSE;
            if (g_pSprite)  hr= g_pSprite->OnResetDevice();
            return S_OK;
        }
        

超初心者の方のために全ソースコードを掲載します。 (^_^;)
全ソースコード

超初心者のプログラム入門(DirectX9 game program)