タイトル : OnPaint の呼び出されるタイミング 投稿日 : 2007/10/08(Mon) 10:14 投稿者 : 魔界の仮面弁士
> OnPaintメソッドが自分の好きなタイミングで呼べない。呼び方がわからない。 3 種類のメソッドがあります。 通常使われるのは、『Invalidate メソッド』です。これが呼ばれると、OS に 「再描画が必要になった」と伝えることができます。OS 側はこの後、再描画を 必要としたタイミングで(メソッド処理後や DoEvents 操作のタイミングなど)、 OnPaint を自動的に呼び出してくれます。このタイミング調整は、OS 側の都合に合わせて 行われるため、再描画回数が不用意に多くならずに済み、実行コストが抑えられます。 また、再描画のタイミングを OS に任せず、自分で強制的に再描画したい場合には、 Invalidate と共に『Update メソッド』を呼び出せば OK です。ただし連続した呼び出しは、 実行コストが高くつきますので、使いどころに気をつけてください。 また、Invalidate + Update の両方の働きを持つ『Refresh メソッド』もあります。 > Onpaintメソッドは勝手に呼ばれているうえに不均等な呼び出し速度。 「画面の内容を更新するタイミング」と「実際に描画を行うタイミング」が、 必ずしも一対一に対応するわけではない、という点に注意してください。 たとえばドラッグ作業などでは、1ドットずれるごとに再描画されるわけではありません。 マウスの移動に応じて「再描画が必要である」という指示が飛んだとしても、実際の再描画は 一度にまとめて処理されます。こうすることによって、素早くドラッグした場合などには、 途中の描画を省略することによって、描画処理が本来の処理を妨げないようにしています。 プログラムからループ処理中に描画する際なども同様です。ループのたびに再描画していては CPU / GPU 負荷が高いので、ループが終わったタイミングや、プロシージャを抜けたタイミングで 再描画が行われるように調整されています。 > Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) Form の OnPaint で、PictureBox に描画しているのは何故でしょうか? ダブルバッファリングを使うなら、引数から得た e.Graphics を使う必要があるかと。 Form の OnPaint で処理するなら、そのまま Form に対して描画すればよいでしょうし、 PictureBox に描画したいのであれば、Form 上に実装するのではなく、PictureBox 自身の OnPaint メソッドないしは Paint イベント を使うべきかと思います。 なお、標準のダブル バッファリングではどうしても機能不足だという場合には、 BufferedGraphicsContext クラスを用いて、独自に実装するという選択肢もあります。 > Dim g As Graphics = PictureBox1.CreateGraphics これはマズイです。作成した Graphics リソースを解放していませんので。 自分で CreateGraphics した Graphics は、毎回解放しなければなりません。 こういう時は、 Using g As Graphics = 〜〜 : End Using の構文を使うようにしてください。 もっとも、ControlStyles.DoubleBuffer を指定したなら、自分で生成するのではなく、 「イベント/メソッド引数で受け取った e.Graphics」を使う事になると思いますが、 この場合は解放不要となります。 (自分で生成したリソースは自分で破棄、OSが生成した分は基本的にOS任せが基本) > Dim brush As SolidBrush = New SolidBrush(Color.Green) こちらも同様。自分で New したブラシは、Using 等できちんと解放しましょう。 逆に、(SystemBrushes などのように)あらかじめ用意されたブラシは、解放不要です。 |