MFCの描画処理でダブルバッファリング(GDI)

MFC

描画処理を行う際に画面にちらつきが発生することがたまにあります。

ちらつきの原因は「背景描画」→「オブジェクト描画」が高速で行われることにあり、対策としては一般的にダブルバッファリングという手法が用いられます。

この記事では、MFCでの描画処理をダブルバッファリングにする方法について解説します。

なお、描画処理については以下の記事で解説していますのでそちらを参考にしてください。

ダブルバッファリング

MFCで描画処理をダブルバッファリングする前に、ちらつきの原因とダブルバッファリングの考え方について簡単に説明します。

ちらつきの原因

冒頭でも説明しましたが、描画処理におけるちらつきの原因は「背景描画」→「オブジェクト描画」が高速で行われることです。

「オブジェクト描画」の後に再度「背景描画」が行われるため、一瞬背景だけが表示されるタイミングが見えることによってちらついているように見えてしまっています。

ダブルバッファリングの考え方

描画時のちらつきの問題は描画処理がここに実行されることが原因となるので、一気に描画が実行されれば問題は解決します。

ダブルバッファリングという手法は、メモリ上に仮想のキャンバス(見えないキャンバス)を作成し、その仮想のキャンバスに対して描画処理を行い、描画処理が一通り終わったところで実キャンバスに仮想キャンバスを貼り付けることで抑制します。

MFCでダブルバッファリングを行う場合には、キャンバスをデバイスコンテキストと置き換えて考えます。

MFCの描画処理をダブルバッファリング

MFCで描画処理を行う場合には、仮想のデバイスコンテキストに描画処理を行い、描画処理が終わったら実デバイスコンテキストに仮想デバイスコンテキストを貼り付けます。

// デバイスコンテキスト
CDC* pDC = this->GetDC();
// 矩形
CRect rc;
// 仮想デバイスコンテキスト
CDC memDC;
// 仮想デバイスコンテキスト用ビットマップ
CBitmap memBmp;

// 矩形取得
this->GetClientRect(rc);
// 仮想デバイスコンテキスト生成
memDC.CreateCompatibleDC(pDC);
// 仮想デバイスコンテキスト用ビットマップ生成
memBmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
// 仮想デバイスコンテキストにビットマップ割り当て
CBitmap* pOldBmp = memDC.SelectObject(&memBmp);

// 描画処理を実施

// 実デバイスコンテキストに仮想デバイスコンテキスト貼り付け
pDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memDC, 0, 0, SRCCOPY);
// 仮想デバイスコンテキストのビットマップを元に戻す
memDC.SelectObject(pOldBmp);
// オブジェクト破棄
memDC.DeleteDC();
memBmp.DeleteObject();
// デバイスコンテキストの解放
this->ReleaseDC(pDC);

「// 描画処理を実施」の場所に「memDC」に対して描画処理を行うことで、ダブルバッファリングを用いた描画が実施されます。

描画処理については以下の記事にまとめていますのでそちらを参考にしてください。

終わりに

MFCでの描画処理をダブルバッファリングにする方法について解説しました。

最近のPCは性能が高いのでダブルバッファリングを行わなくてもちらつきが発生しないこともありますが、使用されるPCの性能や処理の重さによっていつちらつきが発生するかはわからないので基本的には描画処理は全てダブルバッファリングにしておいたほうが良いと思います。

この記事について誤っている点・不明な点などありましたらコメントまでお願いします。

コメント

タイトルとURLをコピーしました