1

CListBox から派生した CMyListBox クラスでオーナー描画戦略を使用しました。リストボックスにアイテムを挿入するときに DrawItem() メソッドを実行するだけです。しかし、メソッドは何度も呼び出されます。必要なときに呼び出すように変更するにはどうすればよいですか。

4

3 に答える 3

1

コンテンツをメモリ内ビットマップに出力してから描画することで、いつでも最初の描画をキャッシュできます。これは、実際のレンダリング コードを再度実行できるように、何かが変更されたときに追跡する必要があることを意味します。レンダリング コードが大量にある場合、毎回レンダリング コードを実行する手間が省けます。

于 2008-10-29T12:13:29.127 に答える
1

ビットマップをキャッシュすることで Kieron が提案していることを正確に実行しましたが、非常に高価なレンダリング コードでのみ実行しました。実際には、項目が強調表示されているか、無効になっているか、通常の状態であるかなどに応じて、キャッシュされた複数の「状態」を保持する必要があります (これはリスト項目ではなくツールバー ボタン用ですが、適用されると思います)。最初に必要になったときにのみ、事前にレンダリングされた画像をキャッシュします。そのようにして、実際に必要な「状態」のみをキャッシュします。

私の描画は純粋な GDI 呼び出しでした。主にビットマップ操作やその他の時間のかかる描画に加えて、あまりにも頻繁に再描画されていました (正当な理由はありませんが、長い話です)。

私が使用していたフレームワーク (MFC と Stingray) の基本を変更することは、選択肢ではありませんでした。キャッシングは、他のすべての最適化が十分ではなかった後の最後の手段でした (くそー遅い仮想マシン!!)。

通常、描画は、無効化されたときに実行するのに十分な速さです (この場合は DrawItem)。DrawItem で正確に何をしているのか見てみたいと思います。他のオプションがない限り、レンダリング自体 (最終的なビットマップなど) ではなく、レンダリングに必要なデータと計算のキャッシュを検討します。

また、Vista のレンダリングがより最適化されていることを読みました。たとえば、ウィンドウが別のウィンドウの後ろから移動された場合に、ウィンドウに描画したものをキャッシュして、無効化/再描画のサイクルを減らすことができます。

于 2008-10-29T13:14:04.260 に答える
0

DrawItem() メソッドは、リストボックス内の任意の項目を描画する必要がある場合に呼び出されます。これに応答しないと、描画されたデータが消去され、更新されていない空白の領域がリスト ボックスに表示される可能性があります。描画が本当に必要ないと思う場合は、次のようにすることができます

void CMyListBox::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
   if (!m_DrawingEnabled)
     return;
}

m_DrawingEnabled は、不要な描画を停止するために維持するメンバーです。

于 2008-10-29T12:06:00.483 に答える