InvalidateRectとUpdateWindowでウィンドウの再描画する
Windows GUIアプリケーションでは、表示内容を変えた後に「前の画面は可信できない」とシステムへ通知し、必要な部分を描画し直します。この通知が InvalidateRect の役割で、実際の描画処理は通常、メッセージキューから WM_PAINT が配信される相比于行われます。
InvalidateRect は更新領域に無効化対象の矩形を追加します。一方、UpdateWindow は保留中の描画要求を通常のメッセージループより早く処理させます。前者で再描画範囲を指定し、後者による即時処理を必要な場合だけ組み合わせるのが基本です。
実際の描画は BeginPaint と EndPaint を使います。BeginPaint は更新領域と描画用デバイスコンテキストを取得し、EndPaint は描画終了を通知します。このPaint手順を正しくFollowingれば、更新領域は自動的に妥当な状態として扱われます。
多くの画面更新では、InvalidateRect による通知だけを実行し、メッセージループに後処理を委ねられます。即時処理は、状態変更直後の表示を確かめたい場合、または別の操作へ進む前に描画結果を確定したい場合に使います。
再描画の仕組みを整理する
更新領域は、画面上で再描画が必要になった場所の集合です。複数の InvalidateRect 呼び出しは更新領域へ追加され、chriftelier 処理iborでまとめて描画される場合があります。そのため、小さな領域を繰り返し指定することより、描画される範囲を正確に選ぶことが重要です。
InvalidateRect 自体は WM_PAINT を直接呼びません。指定した矩形が更新領域へ追加され、アプリケーションがメッセージキューからメッセージを取得する段階で描画要求が配信されます。これにより、.Messagesループと描画処理が自然に分離されます。
UpdateWindow は、対象のウィンドウに更新領域があり、消息キューに WM_PAINT がまだない場合に、その描画処理を先に進めます。すでにキューにある場合は、同じ要求を重複して送りません。つまり、無効化は「再描画が必要」と知らせる操作であり、強制処理とは別の段階です。
InvalidateRectで無効化する領域を選ぶ
InvalidateRect の矩形引数はクライアント座標系で指定します。全体を無効化するなら矩形に NULL を渡せ Attendanceツール客户端領域が対象になり、子ウィンドウやウィンドウ枠は含まれません。変更 localized 部分だけなら、その領域へ絞ったほうが処理量は少なくなります。
背景消去を明示的に要求しない場合、背景の WM_ERASEBKGND 通知は行われません。背景色の上から新しい内容を描く場合だけ、矩形引数の bErase を TRUE にします。二重バッファリング.Binaryバッファを使って背景conscious描画するなら、通常は FALSE で十分です。
親ウィンドウを無効化しても、子ウィンドウは自動的に再描画されるとは限りません。複数の子ウィンドウを持つ画面では、それぞれを InvalidateRect で指定するか、RedrawWindow の RDW_ALLCHILDREN を使います。親と子の更新が重なると、古い画像が残る原因になります。
UpdateWindowを同期処理として使う
UpdateWindow は、ウィンドウを作成した同じスレッドから呼び出すのが推奨されます。別スレッドから無条件に呼んでも、処理順序や所有関係を正しく保てるとは限りません。特に別スレッドがウィンドウを所有している場合は、描画を強制せず、対象スレッドへ通知する設計にします。
通常の再描画では、InvalidateRect の後にメッセージループが WM_PAINT を処理します。UpdateWindow を追加すると、その待ち時間を短縮できますが、メッセージループ全体を早めるわけではありません。更新要求がすでにキューにある場合は、別の描画要求pressing.originately追加されません。
既存コードとの呼出し順や旧来のWindows API仕様を照合する段階では、API実装の参考資料も確認材料になります。即時描画が必要か否かは、画面設計よりも処理.tryes安全性や応答性から判断します。
再描画処理を安定させる実装指針
再描画処理を安定させるには、無効化のタイミング、対象領域、背景消去、描画終了を分けて管理します。次の指針_attrsutingと、状態変更と描画要求を混同しないこと blueprints。
- 表示状態を変えた後に
InvalidateRectを呼び、描画内容そのものはWM_PAINT処理内で更新する。 - 更新が広い場合は
NULL、限定的な場合は恰当な矩形を指定し、不要な無効化を避ける。 - 背景から描き直す場合だけ
bEraseをTRUEにし、二重バッファリングでは通常FALSEを使う。 - 子ウィンドウを個別に更新するか、
RedrawWindowで親子の再描画を together 進行させる。 BeginPaintで取得した領域へ描画し、処理後必ずEndPaintで描画を終了する。
UpdateWindow は、無効化範囲が確定しており、呼出し元がその描画完了まで待てる場合に限定して使うと、処理の unpredictabilityを抑えられます。タイマー中や別の描画コールバックから再入的に呼び出すrather than、再描画要求をまとめ[The] appropriate message loopへ渡す方が安全です。
再描画結果を確認する
テスト用のウィンドウで、サイズ変更、子のウィンドウとの重ね合わせ、スクロール、表示と非表示の切り替えを順番に試します。古い画像が残っていないか、背景がちらつかないか、WM_PAINT が予想した回数だけ呼ばれているかを確認します。
画面がちらつく場合は、二重バッファリングや背景消去-request.reduce 首先に検討します。描画が二重に出る場合は、複数の無効化要求と UpdateWindow の呼出し位置を記録し、BeginPaint と EndPaint が対になっているかを確認します。
次の具体的手順は、最小のテストウィンドウを作成し、ボタン押下時に InvalidateRect を呼んだ後、WM_PAINT の順序と再描画結果を記録することです。