MFCでOnPaintを書き換えてデュアルバッファ描画を実現
3713 ワード
VC/MFCでCDCで描画する場合、頻繁にリフレッシュすると画面が点滅し、CPUの時間占有率がかなり高く、描画効率が極めて低く、プログラムのクラッシュが発生しやすい.
グラフィック画像処理のプログラミング過程において,二重バッファリングは基本的な技術である.フォームがWMに応答している場合PAINTメッセージの場合、複雑なグラフィック処理を行うと、フォームは再描画時にオーバークロックのリフレッシュによって点滅します.この問題を解決する有効な方法はデュアルバッファ技術である.
フォームがリフレッシュされると、元の画像を消去するプロセスOnEraseBkgndが常に必要になるため、背景色を利用してフォームの描画領域を塗りつぶし、新しい描画コードを呼び出して再描画することで、消去すると画像の色のギャップが発生します.WM_PAINTの応答が頻繁な場合、このギャップもますます顕著になります.そこで私たちは点滅現象を見た.
背景色の塗りつぶしを避けるのが最も直接的な方法だと自然に考えられます.でもそうすると、フォームがめちゃくちゃになります.画像を描くたびに元の画像をクリアしないため、画像が残り、フォームが再描画されると画面がめちゃくちゃになることが多い.だから単純に背景の再描画を禁止するだけでは足りない.再描画を行う必要があるが,速度が速いことが要求され,BitBlt関数の使用を考えた.グラフィックブロックのコピーをサポートし、高速です.メモリに図を作成してから、この関数を使用して作成した図をフロントにコピーし、バックグラウンドのリフレッシュを禁止することで、点滅を排除できます.
デュアルバッファが有効になっている場合、画面上の図面ではなく、すべてのペイント操作がメモリバッファに最初に表示されます.すべてのペイント操作が完了すると、メモリバッファはそれに関連付けられた図面に直接コピーされます.このような操作に基づいて、図面領域を直接操作するのではなく、操作メモリに図面を描くので、人の目から見える画面の角度の点滅が緩和されます.
デュアルキャッシュ図面の考え方:1.メモリDCを作成します.2.Bitmapを作図用のキャンバスとして作成します.(物理DCで作成可能なカラーマップ、メモリDCで白黒の場合)3.BitmapをメモリDCに選択します.4.絵を描く.5.メモリDCの内容を物理DCにコピーする.6.DC接続をオフにし、作成したメモリDCとBitmapをクリーンアップします.注意:1.メモリDCは、物理DCサイズと一致している場合は拡大・縮小せず、一致していない場合は拡大・縮小処理を行います.ズームするかどうかはBitBltメソッドとStretchメソッドを使用し、1つはズーム可能です.ここは展開しません.2.DC接続をオフにすることに注意してください.そうしないと、リソースが漏洩しやすくなります.特にGDIリソース.
次のコードは、OnPaint関数に基づいています.
BitBlt関数の説明:
関数プロトタイプ
パラメータhdcDest:ターゲットデバイス環境へのハンドル.nXDest:ターゲット矩形領域の左上隅にあるX軸論理座標を指定します.nYDest:ターゲット矩形領域の左上隅にあるY軸論理座標を指定します.nWidth:ソースとターゲットの長方形領域の論理幅を指定します.nHeight:ソースとターゲットの長方形領域の論理高さを指定します.HDcSrc:ソースデバイス環境へのハンドル.nXSrc:ソース矩形領域の左上隅にあるX軸論理座標を指定します.nYSrc:ソース矩形領域の左上隅にあるY軸論理座標を指定します.dwRop:ラスタ操作コードを指定します.これらのコードは、ソース矩形領域の色データを定義し、ターゲット矩形領域の色データと組み合わせて最後の色を完了する方法を定義します.
グラフィック画像処理のプログラミング過程において,二重バッファリングは基本的な技術である.フォームがWMに応答している場合PAINTメッセージの場合、複雑なグラフィック処理を行うと、フォームは再描画時にオーバークロックのリフレッシュによって点滅します.この問題を解決する有効な方法はデュアルバッファ技術である.
フォームがリフレッシュされると、元の画像を消去するプロセスOnEraseBkgndが常に必要になるため、背景色を利用してフォームの描画領域を塗りつぶし、新しい描画コードを呼び出して再描画することで、消去すると画像の色のギャップが発生します.WM_PAINTの応答が頻繁な場合、このギャップもますます顕著になります.そこで私たちは点滅現象を見た.
背景色の塗りつぶしを避けるのが最も直接的な方法だと自然に考えられます.でもそうすると、フォームがめちゃくちゃになります.画像を描くたびに元の画像をクリアしないため、画像が残り、フォームが再描画されると画面がめちゃくちゃになることが多い.だから単純に背景の再描画を禁止するだけでは足りない.再描画を行う必要があるが,速度が速いことが要求され,BitBlt関数の使用を考えた.グラフィックブロックのコピーをサポートし、高速です.メモリに図を作成してから、この関数を使用して作成した図をフロントにコピーし、バックグラウンドのリフレッシュを禁止することで、点滅を排除できます.
デュアルバッファが有効になっている場合、画面上の図面ではなく、すべてのペイント操作がメモリバッファに最初に表示されます.すべてのペイント操作が完了すると、メモリバッファはそれに関連付けられた図面に直接コピーされます.このような操作に基づいて、図面領域を直接操作するのではなく、操作メモリに図面を描くので、人の目から見える画面の角度の点滅が緩和されます.
デュアルキャッシュ図面の考え方:1.メモリDCを作成します.2.Bitmapを作図用のキャンバスとして作成します.(物理DCで作成可能なカラーマップ、メモリDCで白黒の場合)3.BitmapをメモリDCに選択します.4.絵を描く.5.メモリDCの内容を物理DCにコピーする.6.DC接続をオフにし、作成したメモリDCとBitmapをクリーンアップします.注意:1.メモリDCは、物理DCサイズと一致している場合は拡大・縮小せず、一致していない場合は拡大・縮小処理を行います.ズームするかどうかはBitBltメソッドとStretchメソッドを使用し、1つはズーム可能です.ここは展開しません.2.DC接続をオフにすることに注意してください.そうしないと、リソースが漏洩しやすくなります.特にGDIリソース.
次のコードは、OnPaint関数に基づいています.
CPaintDC dc(this);
CRect rectClient;
CDC dcMem,dcBkgnd;
CBitmap bitmapTemp, *pOldBitmap;
GetClientRect(&rectClient);//
bitmapTemp.CreateCompatibleBitmap(&dc, rectClient.Width(), rectClient.Height());//
dcMem.CreateCompatibelBitmap(&dc); // DC DC
pOldBitmap = dcMem.SelectObject(&bitmapTemp);// dc
//
dcMem.FillSolidRect(rectClient,RGB(255,125,0)); //
/*
*/
dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), &dcMem, 0, 0, SRCCOPY);// dc
dcMem.SelectObject(pOldBitmap);//
BitBlt関数の説明:
関数プロトタイプ
BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop);
パラメータhdcDest:ターゲットデバイス環境へのハンドル.nXDest:ターゲット矩形領域の左上隅にあるX軸論理座標を指定します.nYDest:ターゲット矩形領域の左上隅にあるY軸論理座標を指定します.nWidth:ソースとターゲットの長方形領域の論理幅を指定します.nHeight:ソースとターゲットの長方形領域の論理高さを指定します.HDcSrc:ソースデバイス環境へのハンドル.nXSrc:ソース矩形領域の左上隅にあるX軸論理座標を指定します.nYSrc:ソース矩形領域の左上隅にあるY軸論理座標を指定します.dwRop:ラスタ操作コードを指定します.これらのコードは、ソース矩形領域の色データを定義し、ターゲット矩形領域の色データと組み合わせて最後の色を完了する方法を定義します.