Windowed Mode でビットマップ画像を表示

Windows Mode の画像

今までは画面全体を DirectX が占有して使用していましたが、このモードを Full Screen Mode と呼びます。
高速描画が要求される GAME PROGRAM では Full Screen Mode が使われることが多いのです。
今度は DirectX のプログラムを他の Windows プログラムと共存して表示してみましょう。
一般の Windows プログラムと同じような動かし方をするモードを Windowed Mode と呼びます。

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

プロジェクトの作成

  1. 事前に DirectX9 をインストールしてパスの設定を行って下さい。
    新規プロジェクト(WinMode)を作成して下さい。
    プロジェクトの作成方法は 文字列の Surface を描画する を参照して下さい。
  2. 次のファイルをのフォルダーに格納してプロジェクトに追加して下さい。
    見つからないときは Object Class Library から取得して下さい。
    ソースプログラムは、このページの後に掲載しています。
    ファイル名 ファイルの説明
    WinMode.cpp ソースプログラム
    ddutil.cpp c:\DXSDK\Samples\C++\Common\Src
    ddutil.h c:\DXSDK\Samples\C++\Common\Include
    dxutil.h c:\DXSDK\Samples\C++\Common\Include
  3. プロジェクト/プロパティからリンカ/入力/追加する依存関係で、次のライブラリをリンクして下さい。
    dxguid.lib
    ddraw.lib
    dxerr9.lib
  4. サンプルプログラムの画像ファイルは「桜.bmp」を使っています。
    BMP 形式の適当なファイルを調達してきて下さい。
    if (FAILED(hr = g_pDisplay->CreateSurfaceFromBitmap(&g_pBmpSurface,"c:\\data\\test\\桜.bmp",0,0)))
  5. ビルドから実行を選ぶと、コンパイルに続いて実行が行われます。

プログラムの説明

  1. #define と #include と DirectDraw の領域です。
    ERMSG と SAFE_DELETE を #define で定義しています。
    g_pDisplay はディスプレイ画面の Surface です。
    g_pBmpSurface は画像を格納する Surface です。
    g_bActive は DirectDraw の初期化成功のフラグです。
        #define ERMSG(x)        MessageBox(NULL, x, "DirectX9", MB_OK);
        #define SAFE_DELETE(p)  { if (p) { delete (p);     (p)=NULL; } }
    
        CDisplay*   g_pDisplay    = NULL;
        CSurface*   g_pBmpSurface = NULL;
        BOOL        g_bActive     = FALSE;
        
  2. Windowed Mode では、同時に動いている他のプログラムとの関係でウインドウの切り替えや移動や リサイズなどが起こることを考慮しなければなりません。
    DirectX9 を WindowedMode で初期化するコードです。
    320,240 はウインドウの大きさで表示する画像サイズに合わせています。
    ウインドウのサイズは画像サイズより大きくてもかまいませんが、小さいと画像が表示されません。
        //★ InitDirectDraw()
        HRESULT InitDirectDraw(HWND hWnd)
        {   HRESULT             hr;
    
            g_pDisplay = new CDisplay();
            if (FAILED(hr = g_pDisplay->CreateWindowedDisplay(hWnd,320,240)))
            {   ERMSG("Failed initializing DirectDraw.");
                return hr;
            }
            // Create a surface, and draw a bitmap resource on it.  
            if (FAILED(hr = g_pDisplay->CreateSurfaceFromBitmap
                (&g_pBmpSurface,"c:\\data\\test\\桜.bmp",0,0)))
                return hr;
            return S_OK;
        }
        
  3. WindowedMode の CALLBACK 関数です。
    何かキーがタイプされると、プログラムを終了します。
    ウインドウの移動やサイズ変更の処理が必要です。
        LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
        {   switch (msg)
            {   case WM_KEYDOWN:
                     PostMessage(hWnd,WM_CLOSE,0,0);
                     return 0L;
                case WM_PAINT:
                     if (g_pDisplay)
                     {   if (DisplayFrame() == DDERR_SURFACELOST)
                             PostMessage(hWnd,WM_CLOSE,0,0);
                     }
                     break;
                case WM_MOVE:
                     if (g_pDisplay)    g_pDisplay->UpdateBounds();
                     return 0L;
                case WM_SIZE:
                     if (SIZE_MAXHIDE==wParam||SIZE_MINIMIZED==wParam)  g_bActive= FALSE;
                     else   g_bActive= TRUE;
                     if (g_pDisplay)    g_pDisplay->UpdateBounds();
                     break;
                case WM_DESTROY:
                     FreeDirectDraw();
                     PostQuitMessage(0);
                     return 0L;
            }
            return DefWindowProc(hWnd, msg, wParam, lParam);
        }
        
  4. マウスでドラッグしてウインドウのサイズを変更してみて下さい。
    画面サイズに合わせて画像のサイズやアスペクト比(縦横比)が変わります。
    WM_SIZE: の次の行をコメントにすると画面サイズが変わっても画像は変わらなくなります。
        //    if (g_pDisplay)    g_pDisplay->UpdateBounds();
        

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

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