1

テキストを表示する必要がある mfc アプリケーションがあります。scrollbar を使用するたびに、 OnDraw() 関数が呼び出されます。これは私の OnDraw() 関数です:

CString fileText = pDoc->GetFileText();   //get text from file
CRect rect;
GetClientRect(&rect);

pDC->DrawText(fileText.GetString(), &rect, DT_LEFT|DT_NOCLIP);

スクロールに時間がかかるため、これは効率が悪いようです。問題は、テキストファイル全体をもう一度再描画していることです。GetClipBox 関数を使用して、必要なものだけを再描画したいと考えています。続行する方法について誰か提案してもらえますか?

ありがとう。

4

2 に答える 2

1

ここでは、文字列全体をオフスクリーン ビットマップにまだ描画しているため、ダブル バッファリングは役に立ちません。必要なのは、実際に表示されている文字列の部分だけを描画することですが、これは言うは易く行うは難しです。

まず、各行の高さが同じであれば、10 倍簡単になります (インライン画像、書式設定、段落間隔などの面白いものがないことも想定しています)。基本的にあなたがしたいことは、スクロールバーが総行数に沿ってどれくらい離れているかを導き出すことです (1000 行あり、スクロールバーが 50% にあるとします。つまり、500 行目以降から描画を開始する必要があることを意味します)。表示できるテキストの行数 (コントロールの高さを各行の高さで割ることで簡単に計算できます)。

次に、文字列からそれらの行を抽出し、それらのみを DrawText() に渡します。これを行う最も簡単な方法は、テキスト全体を 1 つの文字列としてではなく、各エントリに 1 行の文字列のベクトルとして格納することです。

最後までスクロールしたときに何を表示するか、半分の行を表示できるようにするかなど、まだ多くの詳細がありますが、基本的には上記のようになります。

さらに、OnDraw() ごとにファイルからテキストを読み取っていないことを願っています。それだけで速度が低下する可能性があるためです。

GetClipBox() はここではあまり関係ありません。1 ピクセルしかスクロールしない場合でも、コンテンツ ウィンドウのコンテンツ全体を再描画する必要があるからです。ポイントは、描画される画面スペースの量を制限するのではなく、描画するもの (DrawText() に渡すもの) の量を減らすことです。

于 2012-07-04T15:17:18.217 に答える
0

あなたの問題に対する最善の解決策は、おそらくダブルバッファリングだと思います。基本的に、画面外のビットマップにペイントしてから、 OnPaint() が呼び出されたら、呼び出すだけです

CRect rcUpdate;
GetClipBox(rcUpdate);
pDC->BitBlt(rcUpdate.left, rcUpdate.top, rcUpdate.Width(), rcUpdate.Height(),
                        m_pMemDC, rcUpdate.left, rcUpdate.top, SRCCOPY);

画面の更新されたセクションをコピーするだけで、パフォーマンスが大幅に向上します。

以前の質問のダブル バッファに役立つコードを投稿しまし。これには、実際には必要なく省略できる GDI+ コードも含まれます。

于 2012-07-04T07:37:38.680 に答える