質問
さて、私のアプリケーションでは、ワイナピといくつかのカスタムコントロールがあります。わーい...
今、通常、彼らは静かにアニメーション、状態の変化、ECTのために自分自身を再描画します。そして、それはすべて正常に機能します。
ただし、Fix()と呼ばれるクラスウィンドウの方法があります。これは、ウィンドウ全体を更新する必要がある場合はいつでも呼び出されます。コントロールを変更し、ウィンドウを無効にします。
これが発生すると、背景が描画され、次にタブコントロールが描かれ、他のすべてが上にあります。これにより、特にウィンドウをサイズ変更する場合は、非常に刺激的な点滅を引き起こします(()fix()への絶え間ない呼び出しのため)。
私が試したこと:
- ws_ex_composited。これは、個々のコントロールを二重にバッファするだけです。その改善ですが、ちらつきは必然的に残ります。
- 背景図面をオフにします。問題はほとんど解決しず、実際に問題を悪化させます。
だから:私は、ウィンドウ全体をダブルバッファーできるようにするために、テクニック/方法/何でも必要です。 WM_Paintメッセージを自分で処理することは解決策かもしれないと考えましたが、どこから始めればいいのかわかりません。私はこれが不可能でさえない恐ろしい感じを持っています...
助けてください、これは重要な問題です。この愚かな小さな問題が修正されたとき、私は非常に安心します。
解決
この時点で、マイクロソフトの深さがネイティブ開発者を無視していることに気付きました。実際、マイクロソフトがネイティブ開発者にWPFに移動させるために、マイクロソフトが意図的にネイティブの絵画を破ったという妄想的な妄想を抱き始めることができます。
まず、検討してください WS_EX_COMPOSITED
. WS_EX_COMPOSITED
マスタードのように思われます: - 子どものコントロールのためにボットンをトップペイントオーダーに施行すること、そして基本的にWM_Paintメッセージがバッチで処理されることを示しています。 Windows 2000(5.0)に追加され、数行下の数行で、デスクトップ構成が有効になっているとは動作しないことが示されています。 IEは、Aero Glassがオフになっていて、誰がそれをするのかを除いて、Windows Vista(6.0)のように動作を停止しますか?
次に、ちらつきのない絵画を機能させようとする2つの「ハック」があります。
- まず、過剰摂取量を模倣する必要があります。
WS_EX_CLIPCHILDREN | WS_EX_CLIPSIBLINGS
窓の特定の領域が一度だけ塗装されていることを確認するために必要です。BeginDeferWindowPos
また、一時的な状態(1つのウィンドウが別のウィンドウが重複する場合)が発生しないようにするために、サイズ変更操作をバッチアップするために必要です(つまり、ウィンドウAがサイズ変更されたが、ウィンドウBにはない場合)。
もちろん、肌のダイアログを描画したり、グループボックス、タブコントロール、またはその他の数の制限を使用しようとしている場合、 WS_EX_CLIPSIBLINGS
適切ではありません。
WM_SETREDRAW
魔法のメッセージです。この機能にアクセスするAPIはありません。WM_SETREDRAW
DefwindowProcによって直接処理され、本質的にウィンドウを隠されているとマークします。後WM_SETREDRAW, FALSE
送信され、親のウィンドウハンドル(およびそのすべての子供)を使用して、getDC/getDcex/getWindowDCなどに電話がかかります。これにより、あなたが終わったら、子供の窓にあらゆる種類のことをする機会が与えられます。WM_SETREDRAW,TRUE
, 、(そして、ウィンドウを手動で塗り直します)。すべての子供の窓は、もちろん、自分の時間にペイントし、親ウィンドウが消去の背景を実行した後、WM_SETREDRAWは万能薬のようなものではありません。
壊れた後 WS_EX_COMPOSITED
, 、.NETのWinFormsとWPFでは、ネイティブコントロールを使用しないようにコントロールをゼロから書き直したので、そこで緩衝塗装で焼くことができました。また、アルファサポートもあります。
他のヒント
hm。人々が急いでこのトピックを複製して閉鎖する前に、あなたの問題はそれ自体が二重のバッファリングではなく、コントロールを再配置するときにちらつきます。「マニュアル」ダブルバッファリングはいくつかのソリューションの1つにすぎません。
それは例かもしれません BeginDeferWindowPos
&友達はちらつきを修正できます。
免責事項:私はかつてWin16 APIのほとんどすべての詳細を知っていましたが、APIレベルのプログラミングを行ってから数年が経ちました。
乾杯&hth。、
- ALF
コードがなければ、実際の状況が何であるかはほとんど想像しません...しかし、wm_erasebkgndを処理しようとすることができます。
取り持つ WM_ERASEBKGND
ウィンドウと実装では、各子供のコントロールの長方を除外し、残りの背景を適切に記入し、フレームワークに背景を返して自分自身を塗装したことを伝えます true
。他のすべての子供コントロールについても同じことを行います。他のすべての子コントロールは、場合には、タブコントロールのような他のコントロールを保持します。
見る ここ MFCを使用した例の場合。
.netにはあります ControlStyle.AllPaintingInWmPaint
各コンテナウィンドウ(メインウィンドウとタブ)に設定する必要があります。 Winapiに相当するものが見つかりませんでした。しかし、これがすることは、背景の絵をwm_erasebkgndからwm_paintに移動することです。また、ちらつきを避けるために、親から子のコントロールの領域を差し引くことができます。これを手動で行う必要がある可能性があります。
WS_EX_COMPOSIETが役に立たないことに驚いています。それは、それをトップレベルのウィンドウに設定し、サブコントロールでRedRawWindowに電話しないでください。
また、DWM/Aeroの有無にかかわらず、必ずテストしてください。さまざまな結果を得ることができます。