セグ16っぽいのを表示するプログラム

セグ16を表示するためのディスプレイを作りました。セグ16についてはこちらを参考。【武蔵野電波のプロトタイパーズ】第4回「16セグメントLEDを使ってみよう」 - PC Watch。それっぽい感じのを作っただけなので、実装は適当です。

このプログラムは列挙体としてセグメントの各ピンを定義して、この列挙体を複合フラグとして扱います。

セグメントの定義

<Flags()> _
Public Enum Segment
    None = 0
    A1 = 1
    M2 = 2
    K3 = 4
    H4 = 8
    U5 = 16
    S6 = 32
    T7 = 64
    G8 = 128
    F9 = 256
    E10 = 512
    DP12 = 1024
    D13 = 2048
    R14 = 4096
    P15 = 8192
    C16 = 16384
    N17 = 32768
    B18 = 65536
End Enum

文字の定義

Dictionaryで文字と複合フラグを関連付けます

Public Class SegmentDictionary
    Inherits Dictionary(Of String, Segment)

    Sub New()
        Dim topHorizonLine As Segment = ConnectSeg(Segment.A1, Segment.B18)
        Dim centerHorizonLine As Segment = ConnectSeg(Segment.U5, Segment.P15)
        Dim bottomHorizonLine As Segment = ConnectSeg(Segment.F9, Segment.E10)

        Dim leftVerticalLine As Segment = ConnectSeg(Segment.H4, Segment.G8)
        Dim centerVerticalLine As Segment = ConnectSeg(Segment.M2, Segment.S6)
        Dim rightVerticalLine As Segment = ConnectSeg(Segment.C16, Segment.D13)

        Dim slashLeftTopRightBottom As Segment = ConnectSeg(Segment.K3, Segment.R14)
        Dim slashRightTopLeftBottom As Segment = ConnectSeg(Segment.N17, Segment.T7)

        Dim leftTopBox As Segment = ConnectSeg(Segment.A1, Segment.H4, Segment.U5, Segment.M2)
        Dim leftDownBox As Segment = ConnectSeg(Segment.U5, Segment.G8, Segment.F9, Segment.S6)
        Dim rightTopBox As Segment = ConnectSeg(Segment.B18, Segment.C16, Segment.P15, Segment.M2)
        Dim rightDownBox As Segment = ConnectSeg(Segment.P15, Segment.D13, Segment.E10, Segment.S6)

        Dim topBox As Segment = ConnectSeg(topHorizonLine, Segment.C16, centerHorizonLine, Segment.H4)
        Dim downBox As Segment = ConnectSeg(bottomHorizonLine, Segment.G8, centerHorizonLine, Segment.D13)

        Dim zero As Segment = ConnectSeg(topHorizonLine, bottomHorizonLine, leftVerticalLine, rightVerticalLine)
        Dim one As Segment = centerVerticalLine
        Dim two As Segment = ConnectSeg(topHorizonLine, Segment.C16, centerHorizonLine, Segment.G8, bottomHorizonLine)
        Dim three As Segment = ConnectSeg(topHorizonLine, centerHorizonLine, bottomHorizonLine, rightVerticalLine)
        Dim four As Segment = ConnectSeg(Segment.H4, centerHorizonLine, rightVerticalLine)
        Dim five As Segment = ConnectSeg(topHorizonLine, Segment.H4, centerHorizonLine, Segment.D13, bottomHorizonLine)
        Dim six As Segment = ConnectSeg(topHorizonLine, Segment.H4, downBox)
        Dim seven As Segment = ConnectSeg(rightVerticalLine, Segment.H4, topHorizonLine)
        Dim eight As Segment = ConnectSeg(topHorizonLine, centerHorizonLine, bottomHorizonLine, leftVerticalLine, rightVerticalLine)
        Dim nine As Segment = ConnectSeg(rightVerticalLine, topHorizonLine, Segment.H4, centerHorizonLine)
        Dim dot As Segment = Segment.DP12


        Dim none As Segment = Segment.None

        Dim smallA As Segment = ConnectSeg(Segment.B18, Segment.C16, rightDownBox)
        Dim smallB As Segment = ConnectSeg(Segment.M2, rightDownBox)
        Dim smallC As Segment = ConnectSeg(Segment.P15, Segment.S6, Segment.E10)
        Dim smallD As Segment = ConnectSeg(Segment.P15, Segment.E10, Segment.S6, rightVerticalLine)
        Dim smallE As Segment = ConnectSeg(rightTopBox, Segment.S6, Segment.E10)
        Dim smallF As Segment = ConnectSeg(centerVerticalLine, centerHorizonLine, Segment.B18)
        Dim smallG As Segment = ConnectSeg(rightTopBox, Segment.D13, Segment.E10)
        Dim smallH As Segment = ConnectSeg(centerVerticalLine, Segment.P15, Segment.D13)
        Dim smallI As Segment = ConnectSeg(Segment.S6)
        Dim smallJ As Segment = ConnectSeg(Segment.E10, rightVerticalLine)
        Dim smallK As Segment = ConnectSeg(centerVerticalLine, Segment.N17, Segment.R14)
        Dim smallL As Segment = ConnectSeg(centerVerticalLine)
        Dim smallM As Segment = ConnectSeg(Segment.G8, centerHorizonLine, Segment.S6, Segment.D13)
        Dim smallN As Segment = ConnectSeg(Segment.S6, Segment.P15, Segment.D13)
        Dim smallO As Segment = ConnectSeg(rightDownBox)
        Dim smallP As Segment = ConnectSeg(rightTopBox, Segment.S6)
        Dim smallQ As Segment = ConnectSeg(rightTopBox, Segment.D13)
        Dim smallR As Segment = ConnectSeg(centerVerticalLine, Segment.N17)
        Dim smallS As Segment = ConnectSeg(Segment.B18, Segment.M2, Segment.P15, Segment.D13, Segment.E10)
        Dim smallT As Segment = ConnectSeg(centerHorizonLine, centerVerticalLine)
        Dim smallU As Segment = ConnectSeg(Segment.S6, Segment.E10, Segment.D13)
        Dim smallV As Segment = ConnectSeg(Segment.D13, Segment.R14)
        Dim smallW As Segment = ConnectSeg(Segment.G8, Segment.T7, Segment.R14, Segment.D13)
        Dim smallX As Segment = ConnectSeg(slashLeftTopRightBottom, slashRightTopLeftBottom)
        Dim smallY As Segment = ConnectSeg(Segment.K3, slashRightTopLeftBottom)
        Dim smallZ As Segment = ConnectSeg(Segment.U5, Segment.T7, Segment.F9)

        Dim bigA As Segment = ConnectSeg(topBox, Segment.G8, Segment.D13)
        Dim bigB As Segment = ConnectSeg(leftTopBox, downBox)
        Dim bigC As Segment = ConnectSeg(topHorizonLine, leftVerticalLine, bottomHorizonLine)
        Dim bigD As Segment = ConnectSeg(topHorizonLine, rightVerticalLine, bottomHorizonLine, leftVerticalLine)
        Dim bigE As Segment = ConnectSeg(topHorizonLine, centerHorizonLine, bottomHorizonLine, leftVerticalLine)
        Dim bigF As Segment = ConnectSeg(topHorizonLine, centerHorizonLine, leftVerticalLine)
        Dim bigG As Segment = ConnectSeg(topHorizonLine, bottomHorizonLine, leftVerticalLine, Segment.P15, Segment.D13)
        Dim bigH As Segment = ConnectSeg(leftVerticalLine, rightVerticalLine, centerHorizonLine)
        Dim bigI As Segment = ConnectSeg(topHorizonLine, centerVerticalLine, bottomHorizonLine)
        Dim bigJ As Segment = ConnectSeg(topHorizonLine, centerVerticalLine, Segment.F9)
        Dim bigK As Segment = ConnectSeg(centerVerticalLine, Segment.N17, Segment.R14)
        Dim bigL As Segment = ConnectSeg(leftVerticalLine, bottomHorizonLine)
        Dim bigM As Segment = ConnectSeg(leftVerticalLine, Segment.K3, Segment.N17, rightVerticalLine)
        Dim bigN As Segment = ConnectSeg(leftVerticalLine, slashLeftTopRightBottom, rightVerticalLine)
        Dim bigO As Segment = ConnectSeg(topHorizonLine, bottomHorizonLine, leftVerticalLine, rightVerticalLine)
        Dim bigP As Segment = ConnectSeg(topBox, Segment.G8)
        Dim bigQ As Segment = ConnectSeg(topHorizonLine, bottomHorizonLine, leftVerticalLine, rightVerticalLine, Segment.R14)
        Dim bigR As Segment = ConnectSeg(topBox, Segment.G8, Segment.R14)
        Dim bigS As Segment = ConnectSeg(topHorizonLine, centerHorizonLine, bottomHorizonLine, Segment.H4, Segment.D13)
        Dim bigT As Segment = ConnectSeg(topHorizonLine, centerVerticalLine)
        Dim bigU As Segment = ConnectSeg(leftVerticalLine, rightVerticalLine, bottomHorizonLine)
        Dim bigV As Segment = ConnectSeg(leftVerticalLine, slashRightTopLeftBottom)
        Dim bigW As Segment = ConnectSeg(leftVerticalLine, rightVerticalLine, Segment.T7, Segment.R14)
        Dim bigX As Segment = ConnectSeg(slashLeftTopRightBottom, slashRightTopLeftBottom)
        Dim bigY As Segment = ConnectSeg(Segment.K3, Segment.N17, Segment.S6)
        Dim bigZ As Segment = ConnectSeg(topHorizonLine, bottomHorizonLine, slashRightTopLeftBottom)

        Me.Add("", none)

        Me.Add("0", zero)
        Me.Add("1", one)
        Me.Add("2", two)
        Me.Add("3", three)
        Me.Add("4", four)
        Me.Add("5", five)
        Me.Add("6", six)
        Me.Add("7", seven)
        Me.Add("8", eight)
        Me.Add("9", nine)


        Me.Add("a", smallA)
        Me.Add("b", smallB)
        Me.Add("c", smallC)
        Me.Add("d", smallD)
        Me.Add("e", smallE)
        Me.Add("f", smallF)
        Me.Add("g", smallG)
        Me.Add("h", smallH)
        Me.Add("i", smallI)
        Me.Add("j", smallJ)
        Me.Add("k", smallK)
        Me.Add("l", smallL)
        Me.Add("m", smallM)
        Me.Add("n", smallN)
        Me.Add("o", smallO)
        Me.Add("p", smallP)
        Me.Add("q", smallQ)
        Me.Add("r", smallR)
        Me.Add("s", smallS)
        Me.Add("t", smallT)
        Me.Add("u", smallU)
        Me.Add("v", smallV)
        Me.Add("w", smallW)
        Me.Add("x", smallX)
        Me.Add("y", smallY)
        Me.Add("z", smallZ)

        Me.Add("A", bigA)
        Me.Add("B", bigB)
        Me.Add("C", bigC)
        Me.Add("D", bigD)
        Me.Add("E", bigE)
        Me.Add("F", bigF)
        Me.Add("G", bigG)
        Me.Add("H", bigH)
        Me.Add("I", bigI)
        Me.Add("J", bigJ)
        Me.Add("K", bigK)
        Me.Add("L", bigL)
        Me.Add("M", bigM)
        Me.Add("N", bigN)
        Me.Add("O", bigO)
        Me.Add("P", bigP)
        Me.Add("Q", bigQ)
        Me.Add("R", bigR)
        Me.Add("S", bigS)
        Me.Add("T", bigT)
        Me.Add("U", bigU)
        Me.Add("V", bigV)
        Me.Add("W", bigW)
        Me.Add("X", bigX)
        Me.Add("Y", bigY)
        Me.Add("Z", bigZ)
    End Sub

    Private Function ConnectSeg(ByVal sourceSeg As Segment, ByVal ParamArray targetSegArr() As Segment) As Segment
        Dim resultSeg As Segment = sourceSeg
        If targetSegArr Is Nothing Then Return resultSeg

        For Each targetSeg As Segment In targetSegArr
            resultSeg = resultSeg Or targetSeg
        Next
        Return resultSeg
    End Function

End Class

表示するためのユーザーコントロール

このユーザーコントロールにはPictureBoxをPictureBox1という名前で配置します。セグメントを表示するためのメソッドとして、DisplaySegmentとDisplayStringという2つのメソッドを外部に公開しています。

Imports System.Windows.Forms

Public Class Seg16Control


#Region "Variables"

    Private _segWidth As Integer
    Private _segHeight As Integer

    Private _padding As Integer
    Private _segmentBold As Integer

    Private _leftTop As Point
    Private _centerTop As Point
    Private _rightTop As Point

    Private _leftCenter As Point
    Private _center As Point
    Private _rightCenter As Point

    Private _leftDown As Point
    Private _centerDown As Point
    Private _rightDown As Point

    Private _displayString As String

    Private _dicSegAction As Dictionary(Of Segment, Action(Of Graphics, Boolean))
    Private _dicSegDisplay As Dictionary(Of String, Segment)

#End Region

#Region "Properties"

#End Region

#Region "Initialize"

    Sub New()

        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。


        InitializeDictionarySeg()

        _dicSegDisplay = New SegmentDictionary

    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        InitializePosition()
    End Sub

    Private Sub InitializePosition()
        _segWidth = Me.Width
        _segHeight = Me.Height

        _padding = CInt(_segWidth / 5)
        _segmentBold = CInt(_padding / 4)

        Dim leftX As Integer = _padding
        Dim centerX As Integer = CInt(_segWidth / 2)
        Dim rightX As Integer = _segWidth - _padding

        Dim topY As Integer = _padding
        Dim centeY As Integer = CInt(_segHeight / 2)
        Dim downY As Integer = _segHeight - _padding

        _leftTop = New Point(leftX, topY)
        _centerTop = New Point(centerX, topY)
        _rightTop = New Point(rightX, topY)

        _leftCenter = New Point(leftX, centeY)
        _center = New Point(centerX, centeY)
        _rightCenter = New Point(rightX, centeY)

        _leftDown = New Point(leftX, downY)
        _centerDown = New Point(centerX, downY)
        _rightDown = New Point(rightX, downY)
    End Sub

    Private Sub InitializeDictionarySeg()
        _dicSegAction = New Dictionary(Of Segment, Action(Of Graphics, Boolean))
        _dicSegAction.Add(Segment.A1, AddressOf DrawSeg1a)
        _dicSegAction.Add(Segment.M2, AddressOf DrawSeg2m)
        _dicSegAction.Add(Segment.K3, AddressOf DrawSeg3k)
        _dicSegAction.Add(Segment.H4, AddressOf DrawSeg4h)
        _dicSegAction.Add(Segment.U5, AddressOf DrawSeg5u)
        _dicSegAction.Add(Segment.S6, AddressOf DrawSeg6s)
        _dicSegAction.Add(Segment.T7, AddressOf DrawSeg7t)
        _dicSegAction.Add(Segment.G8, AddressOf DrawSeg8g)
        _dicSegAction.Add(Segment.F9, AddressOf DrawSeg9f)
        _dicSegAction.Add(Segment.E10, AddressOf DrawSeg10e)
        _dicSegAction.Add(Segment.DP12, AddressOf DrawSeg12)
        _dicSegAction.Add(Segment.D13, AddressOf DrawSeg13d)
        _dicSegAction.Add(Segment.R14, AddressOf DrawSeg14r)
        _dicSegAction.Add(Segment.P15, AddressOf DrawSeg15p)
        _dicSegAction.Add(Segment.C16, AddressOf DrawSeg16c)
        _dicSegAction.Add(Segment.N17, AddressOf DrawSeg17n)
        _dicSegAction.Add(Segment.B18, AddressOf DrawSeg18b)
    End Sub

#End Region

#Region "Display Methods"



    ''' <summary>
    ''' 指定された文字を表示
    ''' </summary>
    ''' <param name="str"></param>
    ''' <remarks></remarks>
    Public Sub DisplayString(ByVal str As String)
        If str Is Nothing Then Throw New ArgumentNullException("str")

        If Me._dicSegDisplay.ContainsKey(str) Then
            DisplaySegment(Me._dicSegDisplay(str))
        End If
    End Sub

    ''' <summary>
    ''' 指定されたセグメントを表示
    ''' </summary>
    ''' <param name="selectSegment"></param>
    ''' <remarks></remarks>
    Public Sub DisplaySegment(ByVal selectSegment As Segment)

        Dim canvas As New Bitmap(PictureBox1.Width, PictureBox1.Height)

        Dim displaySegList As New List(Of Segment)
        Dim notDisplaySegList As New List(Of Segment)


        For Each seg As Segment In [Enum].GetValues(GetType(Segment))
            If (seg And selectSegment) = seg Then
                displaySegList.Add(seg)
            Else
                notDisplaySegList.Add(seg)
            End If
        Next


        Using g As Graphics = Graphics.FromImage(canvas)

            '非表示セグメントの描写
            For Each seg As Segment In notDisplaySegList
                Dim action As Action(Of Graphics, Boolean) = _dicSegAction(seg)
                action.Invoke(g, False)
            Next

            '表示セグメントの描写
            For Each seg As Segment In displaySegList
                If _dicSegAction.ContainsKey(seg) Then
                    Dim action As Action(Of Graphics, Boolean) = _dicSegAction(seg)
                    action.Invoke(g, True)
                End If
            Next

            Me.PictureBox1.Image = canvas
        End Using

    End Sub

#End Region

#Region "Segment"


    Private Sub DrawSeg1a(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _leftTop, _centerTop, isActive)
    End Sub

    Private Sub DrawSeg2m(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _centerTop, _center, isActive)
    End Sub

    Private Sub DrawSeg3k(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _leftTop, _center, isActive)
    End Sub

    Private Sub DrawSeg4h(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _leftTop, _leftCenter, isActive)
    End Sub

    Private Sub DrawSeg5u(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _leftCenter, _center, isActive)
    End Sub

    Private Sub DrawSeg6s(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _center, _centerDown, isActive)
    End Sub

    Private Sub DrawSeg7t(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _center, _leftDown, isActive)
    End Sub

    Private Sub DrawSeg8g(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _leftCenter, _leftDown, isActive)
    End Sub

    Private Sub DrawSeg9f(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _leftDown, _centerDown, isActive)
    End Sub

    Private Sub DrawSeg10e(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _centerDown, _rightDown, isActive)
    End Sub

    Private Sub DrawSeg12(ByVal g As Graphics, ByVal isActive As Boolean)
        'Dim pen As Pen
        'If isActive Then
        '    pen = New Pen(Brushes.Red, _segmentBold)
        'Else
        '    pen = New Pen(Brushes.LightGray, _segmentBold)
        'End If

        'Dim sX As Integer = _rightDown.X + _segmentBold + 5
        'Dim sy As Integer = _rightDown.Y
        'Dim rect As New Rectangle(sX, sy, sX + _segmentBold, sy + _segmentBold)

        'g.DrawRectangle(pen, rect)
    End Sub

    Private Sub DrawSeg13d(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _rightCenter, _rightDown, isActive)
    End Sub

    Private Sub DrawSeg14r(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _center, _rightDown, isActive)
    End Sub

    Private Sub DrawSeg15p(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _center, _rightCenter, isActive)
    End Sub

    Private Sub DrawSeg16c(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _rightTop, _rightCenter, isActive)
    End Sub

    Private Sub DrawSeg17n(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _center, _rightTop, isActive)
    End Sub
    Private Sub DrawSeg18b(ByVal g As Graphics, ByVal isActive As Boolean)
        DrawSegmentLine(g, _centerTop, _rightTop, isActive)
    End Sub

    Private Sub DrawSegmentLine(ByVal g As Graphics, ByVal startPoint As Point, ByVal endPoint As Point, ByVal isActive As Boolean)
        Dim pen As Pen

        If isActive Then
            pen = New Pen(Brushes.Red, _segmentBold)
        Else
            pen = New Pen(Brushes.LightGray, _segmentBold)
        End If

        g.DrawLine(pen, startPoint, endPoint)
    End Sub
#End Region

End Class