1

画像を表示するwxWidgetsC++アプリがあります。画像が別のウィンドウによって隠されているときに、その別のウィンドウを非常にゆっくりとドラッグして画像を明らかにすると、画像には、ペイントされなかった背景色の帯が頻繁に表示されます。

画像はビットマップであり、スクロールペインにレンダリングされます。OnPaint関数は可能な限りシンプルです。DrawBitmap( "use_mask")の最後のパラメーターとしてtrueまたはfalseを使用しても、動作は同じです。

void OnPaint(wxPaintEvent &) {
    wxPaintDC dc(this);
    PrepareDC(dc);
    dc.DrawBitmap(bitmap, 0,0, false);
}

wxBufferedPaintDCを使ってみました。問題は残った。これについて私は何ができますか?

下の画像では、Firefoxウィンドウをゆっくりと右にドラッグして、アプリの画像を表示しています。

縦縞は偽物です

これをWindows7、サービスパック1でテストしています。AMDA6-3620APUとRadeon(tm)HDグラフィックス2.2GHz。VC++2012。wxWidgets2.9.4。

4

2 に答える 2

1

バックグラウンドイベントの消去を無効にします。wxWidgetsが表示を更新したい場合、2つのイベントを発行します。背景の消去イベントとペイントイベントです。バックグラウンド消去イベントには空のメソッドを実装する必要があります(つまり、EVT_ERASE_BACKGROUNDイベントをインターセプトし、event.Skip()を呼び出さないでください)。

ビットマップはパネル全体をカバーするため、背景を消去する必要はありません。

wxClientDCを使用する理由は、「EVT_PAINT()ハンドラー内でwxPaintDCを使用すると、クリッピング領域がウィンドウの損傷した領域に自動的に設定されるためです。この領域の外側に描画しようとしても表示されません。」

クリッピング領域に問題があるため、クリッピング領域を無視すると問題が解決します。

これについては、wxPaintDCおよびwxClientDCクラスリファレンスドキュメントの詳細な説明セクションで説明されています。


これが「より良い」答えのスケッチです。これは、タイマーとすべてのソリューションを再描画するよりもはるかに複雑ですが、システムリソースがはるかに質素であるという意味で優れているため、アプリケーションの応答性が向上します。

2つのことが必要です。

  1. ビットマップを表示するためのより高速な方法

  2. ビットマップの損傷した領域のみを再描画します。

(注:wxPaintDCでDrawBitmapを使用すると、実際にはビットマップ全体が処理され、出力がクリップされます)

ビットマップの一部の表示を高速化するには、ビットマップをメモリDCに描画し、これをどこかに手元に置いておく必要があります(このソリューションはメモリに問題はありませんが、最近のコンピュータでは通常問題にはなりません)。必要な部分をwxPaintDCにブリットすることができます。

wxMemoryDC memdc;
memdc.SelectObject(bitmap);
dc.Blit( ...

Blitパラメータの説明は次のとおりですhttp://docs.wxwidgets.org/2.8/wx_wxdc.html#wxdcblit

損傷した領域だけを処理するには、GetUpdateRegionを呼び出して、リージョンイテレータを使用してreutunを処理する必要があります。スクロールされたパネルを使用しているようです。更新領域は、ビットマップの論理領域ではなく、ウィンドウのクライアント領域に基づいているため、これを考慮する必要があります。

 wxRegionIterator upd(GetUpdateRegion());
 while ( upd )
 {  wxRect rect(upd,GetRect());
    // calculate damaged rectangle in terms of your complete bitmap
    ...
    // blit the calculated rectangle from bitmap in memoryDC to damaged recatngle in wxPaintDC
    ...

    upd++;
 {
于 2012-10-13T22:12:34.420 に答える
1

これはバージョン2.9.4のバグです。以前の安定版ビルド2.8.12には存在しませんでした。スクロールされたウィンドウにのみ影響するようです。

現在のところ最善の解決策は、おそらくビルド2.8.12を使用することです。それが現実的でない場合は、wxClientDCを使用して画像全体をペイントすることで問題を回避できます。たまにしか行わないのが最善です。ストライプが見落とされた可能性がある時期を判断するためのヒューリスティックを思いつきました。これは、更新リージョンの最近の履歴を保持することに基づいています。誤検知が発生しますが、少なくとも私のマシンでは、ちらつきを引き起こすほど多くはありません。

もっと知ったらもっと投稿します。

更新EricJensenは、別の回避策は、OnDrawメソッドをオーバーライドしてペイントを実行し、オンペイントハンドラーをまったく使用しないことであると報告しています。

Windows Aeroテーマを使用している場合、UPDATEの問題は発生しません。

修正済み-http ://trac.wxwidgets.org/ticket/14757

于 2012-10-14T04:39:16.767 に答える