コードの例:CreateCompatibleDC と CreateCompatibleBitmap

ゲームやプレゼンテーション,デモ画面などの
アニメーションを行う画面にて,描画中の表示を
一切見せないようにして,描画が全部完了してから
画面を更新する技術として,「ダブルバッファ」(裏画面)の
技術がある。

Windowsでは,最近ではほとんどDirectXを使っているが,
わざわざDirectXを使うまでもない,単純なアニメーションや
パワーポイントの様なプレゼンテーションの様な表示を行わせるには
CreateCompatibleDC と CreateCompatibleBitmap を使った
画面更新技術が一番簡単。これはかつて WinGといわれてたもので,
Windows Version 3.1 時代(って知ってます?)に登場したもが
Windows95から標準に組み込まれました。

使い方は,一旦通常のウインドウアプリケーションを作成し,
WM_CREATE で CreateCompatibleDC と CreateCompatibleBitmap を使い
裏画面を作成し,WM_PAINTや,WM_TIMER・スレッドなどでアニメーション更新時に
描画するときは,描画対象を全て,作った裏画面のHDCに対して行い,
最後に,BitBltを使って,表画面(通常のウインドウ領域など)にコピーします。

コードを全部書くと,長すぎるので,通常のWindowsアプリケーションに
追加する部分だけ書きます。


// グローバル変数(グローバル変数が気に入らない人はがんばって受け渡ししてねw)
HDC hBackDC; // これが裏画面の書き込み先になります。
HBITMAP hBackBmp; // 背景画像。直接さわることはありません

int iNowTime; // アニメーションに使う時間軸

//ウインドプロシージャ内

case WM_CREATE:
// 他の処理...
SetTimer(hWnd, 500, 10, NULL); // 500ミリ秒に1回WM_TIMERわりこみID = 10で
{
  HDC hDC = GetDC(hWnd); // hWndはウインドウプロシージャのもの
  hBackDC = CreateCompatibleDC(hDC);
  hBackBmp = CreateCompatibleBitmap(hDC, 320,240); // hDCはhBackDCを指定してはいけない![理由] 横幅320ドット,縦幅 240ドット
  SelectObject(hBackDC, hBackBmp); // 裏画面を作成したビットマップに関連付ける。
  ReleaseDC(hWnd, hDC);
}
return 0;


// アニメーション処理など
case WM_TIMER:
if(wParam == 10) {
  HDC hDC;
  RECT rc = {0,0, 320, 240};
  FillRect(hBackDC, &rc, GetStockObject(WHITE_BRUSH) ); // 裏画面を真っ白に塗りつぶす。

  iNowTime++; // 時間軸を動かす

// 描画更新の描画をここに並べる。裏画面に描く
  TextOut(hBackDC, iNowTime, 120, "テストプログラムです", );

// 裏画面から表示画面へコピー。ここで初めて画像が更新される
  hDC = GetDC(hWnd);
  BitBlt(hDC, 0,0, 320, 240, hBackDC, 0,0, SRCCOPY);
  ReleaseDC(hWnd, hDC);
}
break;



case WM_DESTORY
// ウインドウの終了処理を書きます

// 後始末系
DeleteDC(hBackDC);
DeleteObject(hBackBmp);
return 0;



最低限必要なコードは これだけです。




補足:
 320x240で裏画面を用意していますが,ウインドウサイズに合わせたい人は,
 GetClientRect()を使って,rightとbottomを指定しやります。
 ウインドウがリサイズしたときにも対応させるには,ウインドウサイズが変わると
 WM_SIZEが来るので,裏画面を一旦破棄してから,再度作り直します。


この記事へのコメント

この記事へのトラックバック