■11413 / ) |
Re[8]: ListViewのちらつき、仮想化について |
□投稿者/ れい (301回)-(2007/12/13(Thu) 13:00:28)
|
ちらつきをまとめてみました。 やはり私はうそつきでした。今度からうそつきと呼んでください。
しかも前に同じこと調べてました。記憶が混乱してたみたい。 一体何回調べれば覚えるんだろう…。
------------------------------------------------
■言葉の定義 ・ちらつき=フリッカ=flicker=上書きされて消えるべきものが一瞬見えてしまう状態 ・ズレ=テアリング=tearing=フレーム更新中に画像が更新され、ズレてしまう状態
■一般的回避策
・フリッカの回避策 上書きを行わないor実際に表示される前に上書きを終える。 普通はダブルバッファを行う。 メモリ転送が遅ければ、テアリングを助長することもありうる。
・テアリングの回避策 フレーム更新とオンスクリーンバッファの更新が重ならないようにする。 普通は同期して更新する。 ローレベルなサポートがないと対策は困難。 DWMで改善。
■Windows/.Net Windows.Forms におけるフリッカ対策
○あきらめる
○Win32のWS_EX_COMPOSITED
XP以降で用いることができる。
CreateParamsを継承して設定する。
WS_EX_COMPOSITEDを指定したウィンドウおよびその子ウィンドウの描画を オフスクリーンバッファで行い、WM_PAINT終了後に更新するという処理をOSがやってくれる。
CS_CLASSDC、CS_OWNDCを持つウィンドウには適用されない。
その他ScrollBarに対してはうまく効かなかったり、TabControlでごみが残ったり、 トップレベルウィンドウに効かなかったり、 激しくバグあり且つバージョン依存が激しい。
DWMでは問題は減っている。
○.NetのDoubleBuffered / ControlStyles.OptimizedDoubleBuffer
ウィンドウのOnPaint、OnPaintBackgroundをBufferedGraphics対象に行い、 WM_PAINT終了時にBufferedGraphics.Renderすることで ちらつきを防ぐ。
継承してコンストラクタでDoubleBuffered=trueとしたり、 DoubleBufferedをオーバーライドしてreturn trueとしたり、 SetStyleしたりして設定する。
描画にはBufferedGraphicsが用いられる。
ウィンドウ単位でのダブルバッファになるので、子ウィンドウがあるとダメ。
OSによって描画されるコントロール(TextBoxやStatusBar、DateTimePickerなど)は効かない。
ListViewは例外。DoubleBufferedをtrueにするとLVS_EX_DOUBLEBUFFERが適用され、 それによってダブルバッファされる。
○その他の方法
TreeViewはVista以降ならTVS_EX_DOUBLEBUFFER(0x02000000)を指定すればダブルバッファされる。
コントロールがたくさんあってちらつく場合はコントロールをWS_EX_COMPOSITEDなPanelに入れるとよい。
Tabコントロールの場合はTabControlにWS_EX_COMPOSITEDを指定するのではなく、 TabPageにWS_EX_COMPOSITEDを指定するとゴミが出にくい。
■その他。
・ダブルバッファはメモリを大量に食うので注意。 ・うそ情報の可能性が高いので鵜呑みにしない。
|
|