WindowsダイアログでWM_ERASEBKGNDを処理中にちらつきを回避する方法
質問
サイズを変更するダイアログがあります。また、WM_ERASEBKGND呼び出し(現在はFillSolidRectの単純な呼び出し)に応答してペイントするカスタムバックグラウンドもあります。
ダイアログのサイズが変更されると、途方もないちらつきが発生します。ちらつきを減らすために、すべての子ウィンドウを列挙し、それらをクリッピング領域に追加します。これは少し助けになるようです-ちらつきは、すべての子コントロールの再描画時にほとんど明らかです。
サイズ変更中にダイアログをちらつきのないようにするにはどうすればよいですか?ダブルバッファリングは役割を果たすべきだと思いますが、子コントロールを持つダイアログでそれを行う方法はわかりません(すべての子コントロールをオーナー描画またはそのようなものにせずに)。
純粋なWin32ベースのソリューションは歓迎しますが、C ++(.NETではない)とMFCを使用していることに注意してください:
注:私が試したものの、うまくいかなかった1つのこと(理由はわかりません):
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.FillSolidRect(rect, backgroundColor);
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
解決
「FillSolidRect」と仮定します;は背景を消去し、WM_ERASEBKGNDからTRUEを返します。
コードフラグメントでほとんど実行しているダブルバッファリングを実行するには、CreateCompatibleBitmapを使用して、memDCで選択する必要があります。
他のヒント
OnInitDialog関数に次の行を追加してみてください:
ModifyStyle(0, WS_CLIPCHILDREN, 0);
WM_ERASEBKGND処理では何もせず、メインWM_PAINTの一部として消去を行います。無効な領域のみを再描画するようにスマートにペイントするか、より簡単に描画をダブルバッファリングできます。
消去バックグラウンドで何もしないことで、すべての描画コードを1つの場所に置くことができるので、他の人が簡単にフォローおよび保守できます。
WinXP以上をターゲットにしている場合、WS_EX_COMPOSITEDスタイルを使用して、このスタイルのトップレベルウィンドウのデフォルトでダブルバッファリングを有効にすることもできます。これには独自の制限があります。具体的には、GetDCなどを使用してOnPaintサイクルから引き出す必要はありません。
InvalidateRectメソッドの呼び出しのパラメーターをfalseに設定できます。これにより、ウィンドウが再描画されるときにWM_ERASEBKGNDを送信できなくなります。 こちらは、ウィンドウのちらつきを防ぐための素晴らしいリンクです。
ダブルバッファリングは、実際にこれを機能させる唯一の方法です。
CLIPCHILDREN を確認する限り、子コントロールは自分で処理します。