Platform SDK: DirectX |
ここでは、C++ でのアプリケーション開発について説明する。
フルスクリーン モードでは、DirectDraw は表示を排他的に制御する。このため、GDI によって作成されるダイアログ ボックスやその他のウィンドウは通常表示されない。ただし、特殊な方法を使用すれば、Windows のダイアログ ボックス、HTML ヘルプや、アプリケーション内のその他のウィンドウを表示することができる。
FSWindow サンプルでは、フルスクリーン アプリケーションでダイアログ ボックスを表示および更新する方法や、GDI によって表示されたダイアログ ボックスと同様にマウスやキーボード入力を受け付ける方法を示す。
FSWindow では、通常のダイアログ ウィンドウと同様にダイアログ ボックスが作成されて表示される。
hWndDlg = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_SAMPLE), hWnd, (DLGPROC) SampleDlgProc); ShowWindow(hWndDlg, SW_SHOWNORMAL);
もちろん、この時点では、ダイアログ ボックスは隠れている GDI サーフェスによって表示され、Direct Draw によって制御されるプライマリ サーフェスには表示されない。
ハードウェア能力に DDCAPS2_CANRENDERWINDOWED が含まれる場合、(「DDCAPS」参照) ダイアログ ボックスの表示と更新を容易に実行できる。アプリケーションは、IDirectDraw7::FlipToGDISurface メソッドを呼び出すだけで、GDI サーフェスをプライマリ サーフェスにすることができる。それ以後は、GDI が直接フロント バッファにレンダリングされるので、ダイアログ ボックスに対する変更はすべて自動的に表示される。アプリケーションはバック バッファへのレンダリングを続け、各パス上でレンダリング ループによって DirectDraw がバック バッファの内容をフロント バッファにブリットする。フロント バッファがアプリケーション ウィンドウにクリップされ、ダイアログ ボックスがそのウィンドウの一部を覆い隠すので、ダイアログ ボックスが上書きされることはない。
以下のコードは FSWindow_Init 関数の一部である。これにより、クリッパーを作成し、アプリケーション ウィンドウに関連付けて、GDI サーフェスを前面に表示する。
if (ddObject->CreateClipper(0, &ddClipper, NULL) == DD_OK) ddClipper->SetHWnd(0, hwndAppWindow); ddObject->FlipToGDISurface();
次に、FSWindow_Update 関数の以下のコードによって、レンダリングされたバック バッファのコンテンツをクリッピング領域にブリットする。
ddFrontBuffer->SetClipper(ddClipper); ddFrontBuffer->Blt(NULL, ddBackBuffer, NULL, DDBLT_WAIT, NULL);
GDI サーフェスがプライマリ サーフェスなので、Windows によってマウス カーソルが表示される (ただし、アプリケーションが排他協調レベルでマウスによる直接入力を使用している場合は除く)。
DDCAPS2_CANRENDERWINDOWED 能力を持たないハードウェアでは、フルスクリーン モードでのウィンドウの表示と更新処理がやや複雑になる。この場合、GDI によって作成されたウィンドウのイメージをアプリケーションが取得し、フルスクリーン レンダリングが実行された後でバック バッファにブリットする。その後で、バック バッファ全体が通常の方法でフロントにフリップされる。
FSWindow サンプルでは、コンテンツが静的であるか動的であるかに応じて、ウィンドウのディスプレイ メモリにアクセスする 2 つの方法を示す。静的コンテンツの方法の方が、スクリーン デバイス コンテキストではなくメモリ デバイス コンテキストからブリットを行うので、より高速になる。情報表示用のダイアログ ボックスなど、変更しないウィンドウにはこの方法を使用すべきである (ただし、イベントに応答するビットマップを手動で更新しない限り、ボタンが押された状態になるような基本的なアニメーションもユーザーには表示されないので注意すること)。
静的コンテンツの場合、ウィンドウの初期化時に FSWindow が CreateBMPFromWindow 関数を呼び出す。この関数は、ビットマップを作成し、ウィンドウのコンテンツをそのビットマップにブリットする。ビットマップ ハンドルはグローバル変数 hwndFSWindowBMP に格納される。以下に示すように、プライマリ サーフェスを更新しようとすると、常にこのビットマップがバック バッファにブリットされる。
if (FSWindow_IsStatic) { hdcMemory = CreateCompatibleDC(NULL); SelectObject(hdcMemory, hwndFSWindowBMP); BitBlt(hdcBackBuffer, x, y, cx, cy, hdcMemory, 0, 0, SRCCOPY); DeleteDC(hdcMemory); }
これに対し、動的コンテンツの場合は次のコードが実行される。この場合、イメージが GDI サーフェス (hdcScreen デバイス コンテキストで表される) から直接バック バッファにブリットされる。
BitBlt(hdcBackBuffer, x, y, cx, cy, hdcScreen, x, y, SRCCOPY);
上記の座標は、GetWindowRect を呼び出すことによって取得される、GDI サーフェス上のウィンドウの位置とサイズを表す。
DDCAPS2_CANRENDERWINDOWED 能力を持たないハードウェアで FSWindow アプリケーションを実行する場合、GDI サーフェスを使用しないので、Windows はマウス カーソルを表示できない。アプリケーションは、カーソルに関する情報を取得し、フリップの直前のバック バッファ上にその情報を配置することにより、カーソルを表示する。