Microsoft Visual Studio .NET 2003
 Microsoft DirectX 9.0 SDK (December 2004)

■ウィンドウスタイルの切り替え Prev  Top  Next

ウィンドウスタイルの切り替えは、解像度の変更とかウィンドウモード・フルスクリーンモードの切り替えを行うことです。
ここではウィンドウモード・フルスクリーンモードの切り替えについて解説します。
この機能はぶっちゃけ必須ではないですが、プレイヤー側からするとこの機能がついているほうが安心できますので、入れといたほうがいいかもしれません(とかいってGrowWingにいれてなかったりするが)。

さてソースです。

---main.cpp---


//m_pd3dDeviceとm_d3dParametersは初期化済みとする
//LPDIRECT3DDEVICE9 m_pd3dDevice;
//D3DPRESENT_PARAMETERS m_d3dParameters;

//ウィンドウ作成時に使用したウィンドウハンドル
static HWND HWnd;

//キーイベントによりウィンドウスタイルの切り替え要求が発生したか
static BOOL WindowChangeFlg = FALSE;

//ウィンドウの表示位置を格納する。
static RECT WindowPos;

int APIENTRY WinMain( HINSTANCE hInstance,
                      HINSTANCE /*hPrevInstance*/,
                      LPSTR     /*lpCmpLine*/,
                      INT       /*nCmdShow*/)
{
   int nWidth = 640;
   int nHeight = 480;
   DWORD WindowStyle;
   RECT DesctopRc;
   
   //****************************************************************
   //ここでウィンドウクラスの登録処理を行う。
   //****************************************************************
   
   
   //****************************************************************
   //ウィンドウの作成処理
   //****************************************************************
   //初期起動時のウィンドウスタイルを設定する。片方をコメントアウトすること。
   //初期起動がフルスクリーンのとき
   WindowStyle = WS_POPUP;
   //初期起動がウィンドウモードのとき
   WindowStyle = WS_BORDER | WS_CAPTION | WS_SYSMENU;
   HWnd = ::CreateWindow( "ウィンドウスタイルの変更",
                          "ウィンドウスタイルの変更",
                          WindowStyle,
                          0,
                          0,
                          nWidth,
                          nHeight,
                          NULL,
                          NULL,
                          hInstance,
                          NULL );

   //****************************************************************
   //ここでDirect3Dの初期化を行う。
   //****************************************************************

   
   //****************************************************************
   //ウィンドウをスクリーンの中心に移動する
   //****************************************************************
   //デスクトップのサイズを取得する。
   ::GetWindowRect( GetDesktopWindow(), &DesctopRc );

   //ウィンドウモードのときウィンドウをスクリーンの中心に移動する。(注意1)
   if( Windowed == TRUE )
   {
      ::SetWindowPos( HWnd, 
                      HWND_TOP,
                      (int)( DesctopRc.right  * 0.5f - nWidth  * 0.5f ),
                      (int)( DesctopRc.bottom * 0.5f - nHeight * 0.5f ),
                      nWidth,
                      nHeight,
                      SWP_SHOWWINDOW );
   }

   //****************************************************************
   //WindowPos変数の初期化。
   //****************************************************************
   ::SetRect( &WindowPos,
              (int)( DesctopRc.right  * 0.5f - nWidth  * 0.5f ),
              (int)( DesctopRc.bottom * 0.5f - nHeight * 0.5f ),
              (int)( DesctopRc.right  * 0.5f + nWidth  * 0.5f ),
              (int)( DesctopRc.bottom * 0.5f + nHeight * 0.5f ) );

   ::ShowWindow(hWnd, SW_SHOW);
   ::UpdateWindow(hWnd);

   //****************************************************************
   //ここでメッセージループ処理を行う。
   //****************************************************************


}

BOOL MainLoop()
{
   HRESULT hr;
   
   //****************************************************************
   //ウィンドウスタイルの切り替え要求が発生したとき
   //****************************************************************
   if( WindowChangeFlg == TRUE )
   {
      //現在ウィンドウモードのとき
      if( m_d3dParameters.Windowed == TRUE )
      {
         //ウィンドウモードのとき現在のウィンドウの表示位置を保存する。
         //WindowPosは、ウィンドウモードからフルスクリーンへ切り替え、再びウィンドウモードに切り替えたとき、ここで取得した座標でウィンドウを表示する。
         ::GetWindowRect(HWnd, &WindowPos);
         m_d3dParameters.Windowed = FALSE;
      }
      else
         m_d3dParameters.Windowed = TRUE;

      //レンダリングターゲット・深度ステンシルサーフェイス・追加スワップチェーン・ステートブロック・D3DPOOL_DEFAULTリソースを開放する
      //アプリケーションごとに個別に処理する
      Cleanup();

      //デバイスの復元を行う
      m_pd3dDevice->Reset( &m_d3dParameters );

      //レンダリングターゲット・深度ステンシルサーフェイス・追加スワップチェーン・ステートブロック・D3DPOOL_DEFAULTリソースを初期化する
      //アプリケーションごとに個別に処理する
      Init();

      if( m_d3dParameters.Windowed == TRUE )	
      {
         //ウィンドウモードへ変更する。(注意2)
         ::SetWindowLong( HWnd, GWL_STYLE, WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_VISIBLE );
         //ウィンドウモードへ変更したとき、ウィンドウの位置を変更する。
         ::SetWindowPos( HWnd, 
                         HWND_NOTOPMOST,                           //フルスクリーンは最前面表示されているので、解除する。
                         WindowPos.left,
                         WindowPos.top,
                         WindowPos.right  - mWindowPos.left,
                         WindowPos.bottom - mWindowPos.top,
                         SWP_SHOWWINDOW );		
      }
      else
      {
         ::SetWindowLong( HWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE );
         ::SetWindowPos( HWnd, 
                         HWND_TOPMOST,
                         0,
                         0,
                         WindowPos.right  - WindowPos.left,
                         WindowPos.bottom - WindowPos.top,
                         SWP_SHOWWINDOW );         
      }
      
      WindowChangeFlg = FALSE;
   }

   //****************************************************************
    //シーンのクリア
   //****************************************************************
   m_pd3dDevice->Clear( 0L,
                        NULL,
                        D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL,
                        0x0, 
                        1.0f,
                        0L );

   m_pd3dDevice->BeginScene();

   //****************************************************************
   //ここで3Dオブジェクトをレンダリングする。
   //****************************************************************

   m_pd3dDevice->EndScene();

   m_pd3dDevice->Present( NULL, NULL, NULL, NULL );

   return TRUE;
}

やってることは、リストアとほとんど同じです。ウィンドウに対する制御が追加されるぐらいです。

しかしいくつか注意点があります。

(注意1) ::CreateWindowでウィンドウの表示位置をスクリーンの中心になるように指定するとウィンドウスタイルの切り替えに失敗する場合があります。なので初期起動モードがウィンドウモードのときは、Direct3Dの初期化が完了した後、ウィンドウをスクリーンの中心に移動するようにします。

(注意2) ::SetWindowLongを使用するとき、WS_OVERLAPPEDを使用するとフルスクリーンからウィンドウモードへ変更されたときWS_MAXIMIZEBOXを指定しなくても最大化ボタンが表示されたりします。なのでWS_OVERLAPPEDは使用しないほうがよいでしょう。

なお、エラーチェックはやってないのでソースを組み込むときは追加してください。

Prev  Top  Next inserted by FC2 system