投稿者 魔界の仮面弁士  (社会人) 投稿日時 2008/11/28 08:04:07
> Me.PictureBox1.CreateGraphics().DrawLine(iro, 150, 150, 150 + x, 150 + y)
> Me.PictureBox1.CreateGraphics().Dispose()
残念ながらこのコードでは、Grapchis が正しく Dispose されません。

CreateGraphics は、「Graphicsをクリエイト(作成)する」という言葉通り、
呼び出すたびに新たな Graphics オブジェクトを作り出すメソッドです。

そのコードですと、2 つの Grapchics を生成している事になります。
1番目に生成した方は DrawLine するが Dispose していない事になり、
2番目に生成した方は、使わずにただ Dispose しているだけです。


こういう時には、
 Dim g As Grahics = Me.PictureBox1.CreateGraphics()
 g.DrawLine(iro, 150, 150, 150 + x, 150 + y)
 g.Dispose()
と書くようにしてみてください。VB2005, 2008, 2010 の場合は、
 Using g As Graphics = Me.PictureBox1.CreateGraphics()
  g.DrawLine(iro, 150, 150, 150 + x, 150 + y)
 End Using
と書くこともできます(Usingを使う方法を推奨)。


ただし再描画の事を考えると、できれば CreateGraphics を利用した描画方法は
避けた方が良いでしょう。CreateGraphics を使ったサンプルが多く出回ってはいますが、
PicturBox それ自身に描画するのは、あまり好ましい方法ではありません。

本来、PictureBox を使う場合には、
 (方法1) Paint イベントに描画処理を書く。
 (方法2) Image / BackgroundImage プロパティに画像を割り当てる。
という手法を用いた方が都合が良いのです。

そして方法1 の場合、Graphics はイベント引数 e.Graphics から得る事になります。
たとえば、このようになります。

Option Strict On
Public Class Form1
    Private Sub cosS( _
          ByVal g As Graphics, ByVal nagasa As IntegerByVal kakudo As IntegerByVal iro As Pen)
        Dim x As Integer = CInt(nagasa * Math.Cos(kakudo * Math.PI / 180))
        Dim y As Integer = CInt(nagasa * Math.Sin(kakudo * Math.PI / 180))
        g.DrawLine(iro, 150, 150, 150 + x, 150 + y)
    End Sub

    Private Sub PictureBox1_Paint( _
          ByVal sender As ObjectByVal e As PaintEventArgs) Handles PictureBox1.Paint
        Dim i As Integer = 270

        Dim hari As Integer '針 

         hari = Now.Second * 6 + i
        cosS(e.Graphics, 100, hari, Pens.Black)

        hari = Now.Minute * 6 + i
        cosS(e.Graphics, 80, hari, Pens.Aqua)

        Dim ji As Integer = Now.Hour
        hari = (ji * 30 + i) + ji \ 2
        cosS(e.Graphics, 50, hari, Pens.Red)
    End Sub

    Private Sub Timer1_Tick( _
          ByVal sender As ObjectByVal e As EventArgs) Handles Timer1.Tick
       PictureBox1.Invalidate()   '描画して欲しい、と PictureBox にお願いするためのメソッド 
    End Sub

    Private Sub Form1_Load( _
          ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load
        Timer1.Interval = 300
        Timer1.Start()
    End Sub
End Class