2

Invalidate()準備が整う前に呼び出されるため、問題が発生していますOnPaint... Invalidate(new Rectangle(x, y, width, height))1つの領域のみを再描画する必要がある場合は正常に機能しますが、無効にする長方形のコレクションを作成してから、Update()メソッドを使用して再描画する必要がありますすべての無効化されたゾーン。私は と の間Invalidate()で少し迷っていUpdate()ます: それらを使用する方法と、そのためのクリーンな方法は何ですか。

「ラングトンのアリ」や「コンウェイの人生ゲーム」などのセルオートマトンに取り組んでいるため、これを達成する必要があります。小さなグリッドは問題ありませんが、大きなサイズのグリッド (700x500) では、ペイントが非常に重要な問題になります。

だから私の質問はOnPaint、各無効化を呼び出さずに X 長方形を無効OnPaintにしてから、指定された領域のみを更新するように呼び出す方法です (X 長方形 = 少なくとも数百、数千は確実です)。

4

1 に答える 1

6

メソッドを呼び出しInvalidateても、すぐにはPaintイベントが発生しません。指定された領域を無効として設定し、ペイント イベントをキューに入れるだけです。次の呼び出しInvalidateは、リージョンを以前に無効化されたリージョンに追加するだけです。キューにイベントPaintがない場合にのみ、新しいイベントを配置します。Paint

メソッドの備考セクションからInvalidate

Invalidate メソッドを呼び出しても、同期ペイントは強制されません。同期ペイントを強制するにはUpdate、Invalidate メソッドを呼び出した後にメソッドを呼び出します。このメソッドがパラメーターなしで呼び出されると、クライアント領域全体が更新領域に追加されます。


詳細説明:

Win32Windows フォーム テクノロジは、のuser32ライブラリのラッパーです。ペイント イベントの内部を理解するには、user32 がどのように機能するかを知る必要があります。

メッセージ キュー:

Windows のすべてのプロセスにはメッセージ キューがあります。プロセスに属するウィンドウに何かが発生すると、Windows はプロセスのメッセージ キューにイベントをプッシュします。すべてのアプリケーションにはメッセージ ループがあり、( を呼び出して) キューからメッセージを抽出し、メッセージをディスパッチします ( DispatchMessage()を呼び出して、GetMessage()a と呼ばれる適切な関数を呼び出します)。そのため、メッセージは次々と処理されています。これは、メッセージが処理されているとき、他のメッセージを処理できないことを意味します。 そのため、フォームで (新しいスレッドを開始せずに) 時間のかかる操作を行うと、アプリケーションが応答を停止します: 1 つのメッセージの処理でスタックします (たとえば、Window Procedure
Clickボタンのイベント)、アプリケーションは他のメッセージ (マウス イベント、ペイント イベントなど) を処理できません。

Windows フォームでは、Application.Runメソッドはアプリケーションのメッセージ ループを実行します。メッセージはControl.WndProcメソッドに渡され、このメソッドOnXxxxは呼び出す適切なメソッド ( OnKeyPressOnMouseMoveOnResizeなど) を決定し、そのメソッドはそれぞれのイベント ( KeyPressMouseMoveRezieなど) を発生させます。

WM_PAINT:

プログラムのウィンドウを描画する必要がある場合 (たとえば、最初に表示されたとき、または最小化された状態から復元されたとき)、Windowsは、メッセージ キューに未処理のウィンドウWM_PAINTがない場合にのみ、メッセージをメッセージ キューに入れます。また、メッセージループは、キューに他のメッセージがない場合にのみ、キューからメッセージをWM_PAINT抽出します。MSDN のページWM_PAINTからの引用:WM_PAINT

アプリケーションのメッセージ キューに他のメッセージがない場合、GetMessage は WM_PAINT メッセージを返し、DispatchMessage はそのメッセージを適切なウィンドウ プロシージャに送信します。

Windows フォームでは、イベントを発生させるメソッドにWM_PAINT変換されます。OnPaintPaint

Invalidate1 つのメソッドで(Win32 関数を呼び出す)をInvalidateRect数回呼び出したPaint場合でも、イベントが発生する機会はありませんでした。処理中の現在のイベントを終了する必要があり、その間に送信される他のメッセージも処理する必要があります。その後、Paintイベントが発生します。

回答のリンクをたどって、よく読んでください。

于 2013-02-16T18:08:29.573 に答える