tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル画面のちらつきを抑えたい
記事No9336
投稿日: 2009/09/02(Wed) 09:55
投稿者
時計を描画するプログラムを作っているのですが、画面の更新時にちらつきが生じてしまいます。
何か防ぐ方法はありますでしょうか。
VB2008EEです。

==

Imports System.Drawing.Drawing2D

Public Class Form1

    Private Sub Form1_Paint(ByVal sender As Object, _
                            ByVal e As System.Windows.Forms.PaintEventArgs) _
                            Handles MyBase.Paint

        Dim g As Graphics = e.Graphics

        g.TranslateTransform(ClientSize.Width / 2, ClientSize.Height / 2, MatrixOrder.Append)

        Const pai As Double = Math.PI
        Dim center As Point = New Point(0, 0)

        Dim time As DateTime = Now
        Dim secAng As Double = 2.0 * pai * time.Second / 60.0
        Dim minAng As Double = 2.0 * pai * (time.Minute + time.Second / 60.0) / 60.0
        Dim hourAng As Double = 2.0 * pai * (time.Hour + time.Minute / 60.0) / 12.0
        Dim r As Integer = Math.Min(ClientSize.Width, ClientSize.Height) / 2 - 5
        Dim secHandLength As Integer = CType(0.7 * r, Integer)
        Dim minHandLength As Integer = CType(0.9 * r, Integer)
        Dim hourHandLength As Integer = CType(0.5 * r, Integer)

        Dim secHand As Point = New Point(CType(secHandLength * Math.Sin(secAng), Integer), _
                                         CType(-secHandLength * Math.Cos(secAng), Integer))
        Dim minHand As Point = New Point(CType(minHandLength * Math.Sin(minAng), Integer), _
                                         CType(-minHandLength * Math.Cos(minAng), Integer))
        Dim hourHand As Point = New Point(CType(hourHandLength * Math.Sin(hourAng), Integer), _
                                          CType(-hourHandLength * Math.Cos(hourAng), Integer))

        Dim RedPen As Pen = New Pen(Color.Red, 2)
        g.DrawLine(RedPen, center, secHand)

        Dim BlackPen As Pen = New Pen(Color.Black, 5)
        g.DrawLine(BlackPen, center, minHand)

        'Dim BlackPen As Pen = New Pen(Color.Black, 5)
        g.DrawLine(BlackPen, center, hourHand)

        Dim gaiwaku As Pen = New Pen(Color.Black, 5)
        Dim gaiwaku2 As Pen = New Pen(Color.Black, 3)
        g.DrawEllipse(gaiwaku, -r, -r, r * 2, r * 2)

        For i As Integer = 1 To 60
            Dim ang As Double = 2.0 * pai * i / 60.0
            Dim r2 As Integer = 0.9 * r
            If i Mod 5 <> 0 Then
                r2 += (r - r2) / 2
            End If
            Dim p1 As Point = New Point(CType(r * Math.Sin(ang), Integer), _
                                        CType(-r * Math.Cos(ang), Integer))
            Dim p2 As Point = New Point(CType(r2 * Math.Sin(ang), Integer), _
                                        CType(-r2 * Math.Cos(ang), Integer))
            If i Mod 5 = 0 Then
                g.DrawLine(gaiwaku, p1, p2)
            Else
                g.DrawLine(gaiwaku2, p1, p2)
            End If
        Next
        'Me.Refresh()

    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, _
                            ByVal e As System.EventArgs) Handles Timer1.Tick
        Me.Refresh()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                           Handles MyBase.Load
        Me.SetBounds(Me.Left, Me.Top, 301, 301, _
                     BoundsSpecified.Size)
        Dim path As New System.Drawing.Drawing2D.GraphicsPath()
        Me.Top = 0
        Me.Left = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width - Me.Width

        '丸を描く
        path.AddEllipse(New Rectangle(21, 30, 258, 260))
        '真ん中を丸くくりぬく
        'path.AddEllipse(New Rectangle(100, 100, 100, 100))
        Me.Region = New Region(path)

    End Sub
End Class

[ツリー表示へ]
タイトルRe: 画面のちらつきを抑えたい
記事No9338
投稿日: 2009/09/02(Wed) 11:43
投稿者魔界の仮面弁士
> 時計を描画するプログラムを作っているのですが、画面の更新時にちらつきが生じてしまいます。
ダブルバッファリングを有効にしてみてはいかがでしょうか。
http://www.atmarkit.co.jp/fdotnet/dotnettips/197doublebuf/doublebuf.html


>         Dim RedPen As Pen = New Pen(Color.Red, 2)
生成した RedPen や BlackPen 等が解放されていないようです。
Using ブロックで囲むか、使用後に RedPen.Dispose するようにしてください。


>     Private Sub Timer1_Tick(ByVal sender As System.Object, _
>                             ByVal e As System.EventArgs) Handles Timer1.Tick
>         Me.Refresh()
>     End Sub

Tick のたびに画面を再描画する必要があるかどうかを再検討してみてください。
秒針が動かなければ再描画は不要なのですから、Interval が小さい場合には、
「秒針の位置が変化したときのみ、再描画を要請する」方が良いかと思います。

次に、本当に Refresh による強制再描画が必要かどうかを検討してみてください。
今回のようなケースでは、Invalidate でも充分かと思いますよ。
(Invalidate / Update / Reresh の違いについて調べてみてください)

Private previousTime As String = ""
Private Sub Timer1_Tick(ByVal sender As Object, _
                        ByVal e As EventArgs) Handles Timer1.Tick
    Dim currentTime As String = Now().ToString("HHmmss")
    If previousTime <> currentTime Then
        previousTime = currentTime
        Me.Invalidate()
    End If
End Sub

[ツリー表示へ]
タイトルRe^2: 画面のちらつきを抑えたい
記事No9339
投稿日: 2009/09/02(Wed) 13:21
投稿者
魔界の仮面弁士様、ご回答有難うございます。

> ダブルバッファリングを有効にしてみてはいかがでしょうか。
> http://www.atmarkit.co.jp/fdotnet/dotnettips/197doublebuf/doublebuf.html

お陰様で下記をForm1_Loadについきすることによりちらつきはなくなりました。
        Me.SetStyle(ControlStyles.DoubleBuffer, True)
        Me.SetStyle(ControlStyles.UserPaint, True)
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)


> 生成した RedPen や BlackPen 等が解放されていないようです。
> Using ブロックで囲むか、使用後に RedPen.Dispose するようにしてください。

質問以外の箇所についても、ご指摘いただき有難うございます。
確かに解放ということを失念しておりました。
Disposeにて対処させていただきます。


> 今回のようなケースでは、Invalidate でも充分かと思いますよ。
> (Invalidate / Update / Reresh の違いについて調べてみてください)

こちらにつきましてもアドバイス有難うございます。
VB6のときから、Refreshを主に使用していた為、ご提示くださったInvalidate等の存在さえ知りませんでした。
勉強させていただきます。

本当に有難うございました。

[ツリー表示へ]
タイトルRe^3: 画面のちらつきを抑えたい
記事No9341
投稿日: 2009/09/02(Wed) 14:28
投稿者よねKEN

> > ダブルバッファリングを有効にしてみてはいかがでしょうか。
> > http://www.atmarkit.co.jp/fdotnet/dotnettips/197doublebuf/doublebuf.html

そちらは.NET Framework2.0より前の記事です。開発環境がVB2008とのことなので、
以下の同記事の最新版を参照された方がよいと思います。

http://www.atmarkit.co.jp/fdotnet/dotnettips/449doublebufed/doublebufed.html

> お陰様で下記をForm1_Loadについきすることによりちらつきはなくなりました。
>         Me.SetStyle(ControlStyles.DoubleBuffer, True)
>         Me.SetStyle(ControlStyles.UserPaint, True)
>         Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)

これらの設定がDoubleBufferdプロパティの設定1行で済みます。

[ツリー表示へ]
タイトルRe^4: 画面のちらつきを抑えたい
記事No9352
投稿日: 2009/09/05(Sat) 09:29
投稿者れお
健さん>完成品が見たいなぁ。
コレどうやってcloseするんだ?
1 真ん中の○を押すとcloseするの?
2 ん〜、マウスイベントハンドラとかあるのかなぁ〜
3 時計の周りのゲジゲジだが、動かないんだから時計のリソースで
いいんじゃないの?My.resouse.tokeiとかさ。backgroundImageで。
とにかく、完成品がみた〜い!!

[ツリー表示へ]