コードの例: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が来るので,裏画面を一旦破棄してから,再度作り直します。
アニメーションを行う画面にて,描画中の表示を
一切見せないようにして,描画が全部完了してから
画面を更新する技術として,「ダブルバッファ」(裏画面)の
技術がある。
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が来るので,裏画面を一旦破棄してから,再度作り直します。
この記事へのコメント