メソッドを呼び出しInvalidate
ても、すぐにはPaint
イベントが発生しません。指定された領域を無効として設定し、ペイント イベントをキューに入れるだけです。次の呼び出しInvalidate
は、リージョンを以前に無効化されたリージョンに追加するだけです。キューにイベントPaint
がない場合にのみ、新しいイベントを配置します。Paint
メソッドの備考セクションからInvalidate
:
Invalidate メソッドを呼び出しても、同期ペイントは強制されません。同期ペイントを強制するにはUpdate
、Invalidate メソッドを呼び出した後にメソッドを呼び出します。このメソッドがパラメーターなしで呼び出されると、クライアント領域全体が更新領域に追加されます。
詳細説明:
Win32
Windows フォーム テクノロジは、のuser32
ライブラリのラッパーです。ペイント イベントの内部を理解するには、user32 がどのように機能するかを知る必要があります。
Windows のすべてのプロセスにはメッセージ キューがあります。プロセスに属するウィンドウに何かが発生すると、Windows はプロセスのメッセージ キューにイベントをプッシュします。すべてのアプリケーションにはメッセージ ループがあり、( を呼び出して) キューからメッセージを抽出し、メッセージをディスパッチします ( DispatchMessage()を呼び出して、GetMessage()
a と呼ばれる適切な関数を呼び出します)。そのため、メッセージは次々と処理されています。これは、メッセージが処理されているとき、他のメッセージを処理できないことを意味します。
そのため、フォームで (新しいスレッドを開始せずに) 時間のかかる操作を行うと、アプリケーションが応答を停止します: 1 つのメッセージの処理でスタックします (たとえば、Window Procedure
Click
ボタンのイベント)、アプリケーションは他のメッセージ (マウス イベント、ペイント イベントなど) を処理できません。
Windows フォームでは、Application.Run
メソッドはアプリケーションのメッセージ ループを実行します。メッセージはControl.WndProcメソッドに渡され、このメソッドOnXxxx
は呼び出す適切なメソッド ( OnKeyPress
、OnMouseMove
、OnResize
など) を決定し、そのメソッドはそれぞれのイベント ( KeyPress
、MouseMove
、Rezie
など) を発生させます。
プログラムのウィンドウを描画する必要がある場合 (たとえば、最初に表示されたとき、または最小化された状態から復元されたとき)、Windowsは、メッセージ キューに未処理のウィンドウWM_PAINT
がない場合にのみ、メッセージをメッセージ キューに入れます。また、メッセージループは、キューに他のメッセージがない場合にのみ、キューからメッセージをWM_PAINT
抽出します。MSDN のページWM_PAINT
からの引用:WM_PAINT
アプリケーションのメッセージ キューに他のメッセージがない場合、GetMessage は WM_PAINT メッセージを返し、DispatchMessage はそのメッセージを適切なウィンドウ プロシージャに送信します。
Windows フォームでは、イベントを発生させるメソッドにWM_PAINT
変換されます。OnPaint
Paint
Invalidate
1 つのメソッドで(Win32 関数を呼び出す)をInvalidateRect
数回呼び出したPaint
場合でも、イベントが発生する機会はありませんでした。処理中の現在のイベントを終了する必要があり、その間に送信される他のメッセージも処理する必要があります。その後、Paint
イベントが発生します。
回答のリンクをたどって、よく読んでください。