2012-02-06 7 views
1

に点滅:は私がのOnPaintイベントにサブスクライブしていCWindクラスの子供を持っているのOnPaint

BEGIN_MESSAGE_MAP(MyListBox, CWnd) 
    ON_WM_PAINT() 
END_MESSAGE_MAP() 

のOnPaintハンドラで、私は窓に簡単なものを描く場合は、ボーダーのように、すべてが良いです。しかし、もし私がSleep(50);を追加すると(私はいくつかのハード描画操作をシミュレートします)、私のウィンドウが点滅します。私はこのことがなぜ起こるのか理解できません...問題は、OnPaint関数が頻繁に呼び出され、約2〜3回です。

更新:私はダブルビフェリングを使用しています。まず、PaintDeviceContentにウィンドウコンテンツを描画し、このDCをウィンドウのDCにコピーします。

アップデート2:ここにコードがある:まだ描画完了していないものを表示しようとしているので、

void CDirectionsListBox::OnPaint() 
{ 
    CRect rectClient; 
    GetClientRect(rectClient); 

    CPaintDC dc(this); // device context for painting 

    CDC DCMem; 
    DCMem.CreateCompatibleDC(&dc); 

    // Draw window here, workign with DCMem 

    dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), &DCMem, 0, 0, SRCCOPY); 
} 
+0

デバイスコンテキストをコピーするコードを示してください。 – dwo

答えて

1

あなたのウィンドウが点滅している理由です。

MFCを使用して描画する場合、描画操作が重要でない場合は、描画するウィンドウを手動でダブルバッファリングする必要があります。本質的に、あなたがしたいのは、メモリ内の描画コンテキストを作成し、それを描画することです。描画が完了したら、メモリ内のコンテキストにあるものをウィンドウコンテキストにコピーします。

+0

私はダブルバッファリングを使用していると言っていることを忘れてしまいました。 – Seekeer

+0

複雑な描画をシミュレートするためにOnPaintで眠っている問題があると思います。 OnPaintを使用して描画する場合は、ウィンドウメッセージポンプに制御を戻すためにすばやく戻るようにします。あなたは本当にあなたのバックバッファのどこかに描画を行う必要がありますし、OnPaintメソッドでは、バックバッファの内容だけをウィンドウにblitします。 – Dervall

+0

"高価な"図面をヘルパーメソッドに入れてasyncと呼ぶことをお勧めしますか? – Seekeer

4

デフォルトでは、バックグラウンドブラシを使用してクライアント領域をクリアすることによって、バックグラウンドがペイントされます。あなたはそれをオフにしたい。とにかく既存の画像の上にblitするつもりであるので、WM_ERASEBKGNDを処理して何もしないでください。

How to avoid flicker while handling WM_ERASEBKGND in Windows dialog

+0

問題は、OnPaintが発生するたびにちらつきが発生しないことです。しかし、 'OnPaint'の実行時間を増やすと、毎回ちらつきが発生します。 これは何とか関数の実行時間と関連していると思われますが、なぜそれが理解できないのですか? 'WM_ERASEBKGND'を処理しようとしましたが、ちらつきは残っていますが、TRUEまたはFALSEを返しても問題ありません。 – Seekeer

+0

正解です。それが助けにならない場合は、実装に関係のない他のいくつかの問題があります。 MFCでのダブルバッファリングはすべて3つのことです:全てをビットマップ(例えば 'CMemDC')に描画し、ベースクラスを呼び出さないようにするか(または' WM_PAINT'メッセージがバッファされたHDCと結合して送信されることを避ける) 'WM_ERASEBKGND'。 – l33t

+1

@Seekeer:もちろん、Blitがフリッカーに影響する前に 'OnPaint'で費やした時間は、消去された背景が画面上にある時間を決定するためです。リフレッシュサイクル中に消去とブリットの両方を行うと、消去されたバックグラウンドはビデオカードよりも大きくなりません(物理ディスプレイには表示されません)。消去とblitとの間に遅延がある場合、消去された画面は数フレームの間ディスプレイに表示され、ユーザーが気付くことができます。 –

関連する問題