
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports System.Collections
Imports System.IO
Imports System.Reflection
Imports IPS7Lnk



Structure MyDataType
  Private dummy As String
  Public Const [Byte] As Integer = 0
  Public Const Word As Integer = 1
  Public Const Real As Integer = 2
  Public Const DWord As Integer = 3
  Public Const Bit As Integer = 4
End Structure


Public Class Form1
  Private Plc As IPS7 = New IPS7
  Private m_bConnected As Boolean
  Private m_bOpened As Boolean
  Private m_uStartAt As UInteger
  Private m_DataArea As Char
  Private m_uCount As UInteger
  Private m_uDBNo As UInteger
  Private m_uRackNr As UInteger
  Private m_uSlotNr As UInteger
  Private m_uPlcType As UInteger
  Private m_uChannel As UInteger
  Private m_uAccessMode As UInteger
  Private m_KeepAliveInterval As UInteger
  Private m_KeepAliveTime As UInteger
  Private m_bUseKeepAlive As Boolean
  Private m_WordBuf() As System.UInt16 = New System.UInt16(2048) {}
  Private m_DoubleBuf() As Double = New Double(2048) {}
  Private m_DWordBuf() As UInteger = New UInteger(2048) {}
  Private m_ByteBuf() As Byte = New Byte(2048) {}
  Private m_Err As Integer
  Private m_DataAreas() As Char = {"E", "A", "M", "D", "T", "Z"}
  Private bsD As BindingSource = New BindingSource


  Public Sub New()
    MyBase.New()
    InitializeComponent()
    cbDataArea.SelectedIndex = 0
    cbPlcType.SelectedIndex = 0
    cbChannel.SelectedIndex = 0
    SetbOpened(False)
    listData.GridLines = True
    listData.Columns(0).Text = "Adr / Addr"
    listData.Columns(1).Text = "Wert/Value(dec.)"
    listData.Columns(2).Text = "Wert/Value(hex)"
    listData.Columns(3).Text = "ASCII"
    listData.Columns(0).AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize)
    listData.Columns(1).AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize)
    listData.Columns(2).AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize)
    listData.Columns(3).AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize)
    Dim Fi As FileInfo
    Fi = New FileInfo(Assembly.GetExecutingAssembly.Location)
    helpProvider.HelpNamespace = (Fi.DirectoryName + "\\ips7lnk.chm")
    StatusTimer.Start()
    If File.Exists("oem.bmp") Then
      Logo.Load("oem.bmp")
    End If
  End Sub

  ' Datarows from PLC
  Private Sub SetbOpened(ByVal bOpened As Boolean)
    m_bConnected = False
    m_bOpened = bOpened
    Start.Enabled = bOpened
    Count.Enabled = bOpened
    DBNr.Enabled = bOpened
    btnClose.Enabled = bOpened
    btnRdB.Enabled = bOpened
    cbDataArea.Enabled = bOpened
    btnRdReal.Enabled = bOpened
    btnRdDW.Enabled = bOpened
    btnRdW.Enabled = bOpened
    btnRdMulti.Enabled = bOpened
    btnConnect.Enabled = bOpened

    cbChannel.Enabled = Not bOpened
    cbPlcType.Enabled = Not bOpened
    Rack.Enabled = Not bOpened
    Slot.Enabled = Not bOpened
    btnOpen.Enabled = Not bOpened
    IPAddress.Enabled = Not bOpened
    checkUseKeepAlive.Enabled = Not bOpened
    KeepAliveInterval.Enabled = Not bOpened
    KeepAliveTime.Enabled = Not bOpened
    cbChannel.Enabled = Not bOpened

    ShowConnectStatus()
  End Sub

  
  Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click
    Dim lRef As Integer

    If (IPAddress.Text.Length = 0) Then
      MessageBox.Show("Bitte IP-Adresse eingeben. / Please enter ip address.", Me.Text)
      Return
    End If



    m_uRackNr = UInteger.Parse(Rack.Text)
    m_uSlotNr = UInteger.Parse(Slot.Text)
    m_uChannel = CType(cbChannel.SelectedIndex, UInteger)
    m_uPlcType = CType(cbPlcType.SelectedIndex, UInteger)
    m_bUseKeepAlive = checkUseKeepAlive.Checked

    If (m_uPlcType = 0) Then
      ' S7-300 / 400
      If (m_uChannel = 0) Then
        ' OP
        m_uAccessMode = IPS7.AM.OP_S7300_400
      Else
        ' PG
        m_uAccessMode = IPS7.AM.PG_S7300_400
      End If
    Else
      ' S7200
      m_uAccessMode = IPS7.AM.S7200
    End If
    m_Err = Plc.OpenEx(IPAddress.Text, m_uRackNr, m_uSlotNr, 0, 0, m_uAccessMode, 10000, 10000, 10000)

    If (lRef < 0) Then
      m_Err = lRef
    Else
      m_Err = 0
    End If

    ShowStatus()
    If (m_Err = 0) Then
      SetbOpened(True)
      If m_bUseKeepAlive Then
        m_KeepAliveInterval = UInteger.Parse(KeepAliveInterval.Text)
        m_KeepAliveTime = UInteger.Parse(KeepAliveTime.Text)
        If m_KeepAliveInterval >= 10 AndAlso m_KeepAliveTime >= 100 Then
          Plc.SetKeepAlive(m_KeepAliveInterval, m_KeepAliveTime)
        End If
      End If
    End If
  End Sub

  Private Function GetResultString(ByVal Err As Integer) As String
    Dim SocketErr As Integer
    Dim S As String

    Select Case Err
      Case IPS7.Result.E_NOERR
        S = "Aktion erfolgreich. / Action was successfull!"
        Exit Select

      Case IPS7.Result.E_NODATA
        ' Datenbereich in der SPS nicht vorhanden
        S = "Datenbereich oder DB nicht vorhanden. / Data area DB does not exist!"
        Exit Select

      Case IPS7.Result.E_TIMEOUT
        S = "Zeitüberlauf! / Timeout!"
        Exit Select

      Case IPS7.Result.E_SOCKERR
        SocketErr = Plc.GetSockErr()
        S = String.Format("Socketfehler Nr: {0:D} aufgetreten. / Socket error no:{1:D} occurred!", SocketErr, SocketErr)
        Exit Select

      Case IPS7.Result.E_TYPE_NOTSUPPORTED
        S = "Datentyp oder Format wird nicht unterstützt! / Data type or data format not supported!"
        Exit Select

      Case IPS7.Result.E_PC_BUFSIZE
        S = "Das übergebene Array hat zuwenig Elemente. / The Array you passed is to small."
        Exit Select

      Case IPS7.Result.E_ALREADY_OPENED
        S = "Die Open-Funktion wurde bereits aufgerufen. / The Open was called already."
        Exit Select

      Case IPS7.Result.E_BADDATATYPE
        S = "Multi-Access : Gewünschter SPS oder PC Datentyp nicht möglich / desired PLC or PC data type not available"
        Exit Select

      Case IPS7.Result.E_PC_S7_DATATYPE_BAD_REL
        S = "Multi-Access : PC und S7-Datentyp stehen int falscher Relation / PC and S7 -datatype beeing in bad relations"
        Exit Select

      Case IPS7.Result.E_BADDATACOUNT
        S = "Multi-Access : SPS liefert falsche Anzahl an Daten / PLC sends bad count of data"
        Exit Select
      Case Else

        S = String.Format("Unbekannter Fehler aufgetreten. / Unknown error occured! (Nummer/Number: {0:d})", Err)
        Exit Select
    End Select
    Return (S)
  End Function

  Private Sub ShowStatus()
    Dim S As String = GetResultString(m_Err)
    Status.Text = S
    If (m_Err <> 0) Then
      Status.BackColor = Color.LightPink
    Else
      Status.BackColor = Color.LightGreen
    End If
  End Sub

  Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnd.Click
    Close()
  End Sub

  Private Sub btnRdW_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRdW.Click
    If UpdateData(True) Then
      Status.Text = "Beschäftigt ... / busy ..."
      Status.Refresh()
      Me.Cursor = Cursors.WaitCursor
      m_Err = Plc.Rd(m_DataArea, m_uDBNo, m_uStartAt, m_uCount, m_WordBuf)
      FillDataList(1)
      Me.Cursor = Cursors.Default
    End If
    ShowStatus()
  End Sub

  Private Sub btnRdReal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRdReal.Click
    If UpdateData(True) Then
      Status.Text = "Beschäftigt ... / busy ..."
      Status.Refresh()
      Me.Cursor = Cursors.WaitCursor
      m_Err = Plc.Rd(m_DataArea, m_uDBNo, m_uStartAt, m_uCount, m_DoubleBuf)
      FillDataList(2)
      Me.Cursor = Cursors.Default
    End If
    ShowStatus()
  End Sub

  Private Sub btnRdDW_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRdDW.Click
    If UpdateData(True) Then
      Status.Text = "Beschäftigt ... / busy ..."
      Status.Refresh()
      Me.Cursor = Cursors.WaitCursor
      m_Err = Plc.Rd(m_DataArea, m_uDBNo, m_uStartAt, m_uCount, m_DWordBuf)
      FillDataList(3)
      Me.Cursor = Cursors.Default
    End If
    ShowStatus()
  End Sub

  Private Function UpdateData(ByVal bGet As Boolean) As Boolean
    If bGet Then
      ' Daten
      m_DataArea = m_DataAreas(cbDataArea.SelectedIndex)
      ' Db oder DX
      If (m_DataArea = "D") Then
        If (DBNr.Text.Length = 0) Then
          MessageBox.Show("Bitte DB-Nummer eingeben. / Please enter number of DB.", Me.Text)
          Return False
        End If
        m_uDBNo = UInteger.Parse(DBNr.Text)
      Else
        m_uDBNo = 0
      End If

      If (Count.Text.Length = 0) Then
        MessageBox.Show("Bitte Anzahl eingeben. / Please enter a value for count.", Me.Text)
        Return False
      End If

      m_uCount = UInteger.Parse(Count.Text)
      If (Start.Text.Length = 0) Then
        MessageBox.Show("Bitte Start eingeben. / Please enter a value for start.", Me.Text)
        Return False
      End If
      m_uStartAt = UInteger.Parse(Start.Text)
      Return True
    End If
    Return False
  End Function

  Private Sub btnRdB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRdB.Click
    If UpdateData(True) Then
      Status.Text = "Beschäftigt ... / busy ..."
      Status.Refresh()
      Me.Cursor = Cursors.WaitCursor
      m_Err = Plc.Rd(m_DataArea, m_uDBNo, m_uStartAt, m_uCount, m_ByteBuf)
      Me.Cursor = Cursors.Default
      FillDataList(0)
    End If
    ShowStatus()
  End Sub

  Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
    m_Err = Plc.Close
    SetbOpened(False)
    ShowStatus()
  End Sub

  Private Function GetAddrName(ByVal DataType As Integer, ByVal DataArea As Char, ByVal DBNo As UInteger) As String
    If DataArea = "D" Then
      If DataType <= MyDataType.Word Then
        Return String.Format("DB{0}.DB{1}", DBNo, If(DataType = 0, "B", "W"))
      ElseIf DataType = MyDataType.DWord OrElse DataType = MyDataType.Real Then
        ' 2 oder 3 = Doppelwort bzw Real
        Return String.Format("DB{0}.DBD", DBNo)
      ElseIf DataType = MyDataType.Bit Then
        Return String.Format("DB{0}.DBX", DBNo)
      Else
        Return ("")
      End If
    ElseIf DataArea = "T" Then
      Return "T "
    ElseIf DataArea = "Z" Then
      Return "Z "
    Else
      If DataType <= MyDataType.Word Then
        Return String.Format("{0}{1}", DataArea, If((DataType = 0), "B"c, "W"c))
      ElseIf DataType = MyDataType.DWord OrElse DataType = MyDataType.Real Then
        ' 2 oder 3 = Doppelwort bzw Real
        Return String.Format("{0}D", DataArea)
      ElseIf DataType = MyDataType.Bit Then
        Return String.Format("{0}", DataArea)
      Else
        Return ("")
      End If
    End If
  End Function

  Private Function GetAddrName(ByVal DataType As Integer) As String
    Return (GetAddrName(DataType, m_DataArea, m_uDBNo))
  End Function

  Private Sub FillDataList(ByVal DataType As Integer)
    ' 0 = byte, 1 = Word, 2 = Real,3 = DWord
    Dim i As Integer
    Dim Steps As Integer
    Dim SAddr As String

    listData.BeginUpdate()
    listData.Items.Clear()

    If (m_Err = 0) Then
      SAddr = GetAddrName((DataType))

      If (DataType = 0) Then ' byte
        i = 0
        Do While (i < CType(m_uCount, Integer))
          Dim C1 As Char
          Dim S As String
          Dim liv As ListViewItem = listData.Items.Add((SAddr + String.Format("{0}", (m_uStartAt + i))))

          liv.SubItems.Add(String.Format("{0:D}", m_ByteBuf(i)))
          liv.SubItems.Add(String.Format("0x{0:X2}", m_ByteBuf(i)))

          C1 = System.Convert.ToChar(m_ByteBuf(i))
          If (C1 <> System.Convert.ToChar(0)) Then
            S = String.Format("'{0:C}'", C1)
          Else
            S = " "
          End If

          liv.SubItems.Add(S)
          i = (i + 1)
        Loop
      ElseIf (DataType = 1) Then 'Wort
        If (m_DataArea <> "Z") Then
          Steps = 2
        Else
          Steps = 1
        End If

        i = 0
        Do While (i < CType(m_uCount, Integer))
          Dim C2 As Char
          Dim C1 As Char
          Dim S As String
          Dim liv As ListViewItem = listData.Items.Add((SAddr + String.Format("{0}", (m_uStartAt _
                              + (i * Steps)))))
          liv.SubItems.Add(String.Format("{0:D}", m_WordBuf(i)))
          liv.SubItems.Add(String.Format("0x{0:X4}", m_WordBuf(i)))
          C1 = System.Convert.ToChar((m_WordBuf(i) And &HFF))
          C2 = System.Convert.ToChar((m_WordBuf(i) + 8))
          'S = "'" + C2.ToString() + C1.ToString() + "'";
          If (C1 <> System.Convert.ToChar(0)) Then
            S = String.Format("'{0:C}'", C1)
          Else
            S = " "
          End If

          If (C2 <> System.Convert.ToChar(0)) Then
            S = S + String.Format("'{0:C}'", C2)
          Else
            S = " "
          End If
          liv.SubItems.Add(S)
          i = (i + 1)
        Loop
      ElseIf (DataType = 2) Then 'Real/Double
        Steps = 4
        i = 0
        Do While (i < CType(m_uCount, Integer))
          Dim liv As ListViewItem = listData.Items.Add((SAddr + String.Format("{0}", (m_uStartAt _
                              + (i * Steps)))))
          liv.SubItems.Add(String.Format("{0:F}", m_DoubleBuf(i)))
          i = (i + 1)
        Loop
      ElseIf (DataType = 3) Then 'Doppelwort
        If (m_DataArea <> "T") Then
          Steps = 4
        Else
          Steps = 1
        End If
        i = 0
        Do While (i < CType(m_uCount, Integer))
          Dim C4 As Char
          Dim C1 As Char
          Dim C2 As Char
          Dim C3 As Char
          Dim S As String
          Dim liv As ListViewItem = listData.Items.Add((SAddr + String.Format("{0}", (m_uStartAt _
                              + (i * Steps)))))
          liv.SubItems.Add(String.Format("{0:D}", m_DWordBuf(i)))
          liv.SubItems.Add(String.Format("0x{0:X8}", m_DWordBuf(i)))

          C1 = System.Convert.ToChar((m_WordBuf(i) And &HFF))
          C2 = System.Convert.ToChar((m_WordBuf(i) >> 8 And &HFF))
          C3 = System.Convert.ToChar((m_WordBuf(i) >> 16 And &HFF))
          C4 = System.Convert.ToChar((m_WordBuf(i) >> 24 And &HFF))

          'S = "'" + C2.ToString() + C1.ToString() + "'";
          If (C1 <> System.Convert.ToChar(0)) Then
            S = String.Format("'{0:C}'", C1)
          Else
            S = " "
          End If

          If (C2 <> System.Convert.ToChar(0)) Then
            S = S + String.Format("'{0:C}'", C2)
          Else
            S = S + " "
          End If

          If (C3 <> System.Convert.ToChar(0)) Then
            S = S + String.Format("'{0:C}'", C3)
          Else
            S = S + " "
          End If

          If (C4 <> System.Convert.ToChar(0)) Then
            S = S + String.Format("'{0:C}'", C4)
          Else
            S = S + " "
          End If

          liv.SubItems.Add(S)
          i = (i + 1)
        Loop
      End If
    End If
    listData.EndUpdate()
  End Sub

  Private Sub cbDataArea_SelectedIndexChanged_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbDataArea.SelectedIndexChanged
    m_DataArea = m_DataAreas(cbDataArea.SelectedIndex)

    btnRdReal.Enabled = False
    btnRdB.Enabled = False
    btnRdW.Enabled = False
    DBNr.Enabled = False
    btnRdDW.Enabled = False

    If Not m_bOpened Then
      Exit Sub
    End If

    If m_DataArea = "T" Then
      btnRdDW.Enabled = True

    ElseIf m_DataArea = "Z" Then
      btnRdW.Enabled = True
    Else
      btnRdReal.Enabled = True
      btnRdB.Enabled = True
      btnRdW.Enabled = True
      btnRdDW.Enabled = True

    End If
    If m_DataArea = "D" Then
      DBNr.Enabled = True
    End If
  End Sub


  Private Sub btnRdMulti_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRdMulti.Click
    Dim Cnt As Integer
    Cnt = 10
    Dim Rq As IPS7RdMulti() = New IPS7RdMulti(Cnt - 1) {}

    For i As Integer = 0 To Cnt - 1
      Rq(i) = New IPS7RdMulti()
    Next


    Cnt = 0

    Rq(Cnt).Bit(CChar("E"), 0, 4, 0, 32, m_ByteBuf)
    ' lese ab E 4.0 32 Bit
    Rq(Cnt).UserData0 = MyDataType.Bit
    Rq(Cnt).UserData1 = 0
    ' StartIndex Zielspeicher
    Cnt += 1

    Rq(Cnt).[Byte](CChar("E"), 0, 0, 20, m_ByteBuf(40))
    ' EB0 20 Byte
    Rq(Cnt).UserData0 = MyDataType.[Byte]
    Rq(Cnt).UserData1 = 40
    ' StartIndex Zielspeicher
    Cnt += 1

    Rq(Cnt).Word(CChar("E"), 0, 20, 1, m_WordBuf(0))
    ' EB 20 1 Wort
    Rq(Cnt).UserData0 = MyDataType.Word
    Rq(Cnt).UserData1 = 0
    ' StartIndex Zielspeicher
    Cnt += 1

        Rq(Cnt).Word(CChar("D"), 100, 0, 150, m_WordBuf(10))
    ' DB10.DW 0 150 Worte
    Rq(Cnt).UserData0 = MyDataType.Word
    Rq(Cnt).UserData1 = 10
    ' StartIndex Zielspeicher
    Cnt += 1

        Rq(Cnt).Word(CChar("D"), 100, 1, 150, m_WordBuf(250))
    ' EB 0 20 Byte in Realbuffer lesen
    Rq(Cnt).UserData0 = MyDataType.Word
    ' 
    Rq(Cnt).UserData1 = 250
    ' StartIndex Zielspeicher
    Cnt += 1


        Rq(Cnt).Real(CChar("D"), 100, 0, 60, m_DoubleBuf(0))
    ' DB10.DBB0 60 Realwerte
    Rq(Cnt).UserData0 = MyDataType.Real
    Rq(Cnt).UserData1 = 0
    ' StartIndex Zielspeicher
    Cnt += 1

        Rq(Cnt).DWord(CChar("D"), 100, 200, 20, m_DWordBuf(0))
    ' D10 DBB 200 20 Doppelworte
    Rq(Cnt).UserData0 = MyDataType.DWord
    Rq(Cnt).UserData1 = 0
    ' StartIndex Zielspeicher
    Cnt += 1


    Rq(Cnt).DWord(CChar("D"), 310, 77, 50, m_DWordBuf(20))
    ' DB10 DB77 50 Doppelworte
    Rq(Cnt).UserData0 = MyDataType.DWord
    Rq(Cnt).UserData1 = 20
    ' StartIndex Zielspeicher
    Cnt += 1



    Rq(Cnt).Timer(CChar("T"), 0, 5, 10, m_DWordBuf(100))
    ' T5 10 Timer
    Rq(Cnt).UserData0 = MyDataType.DWord
    '
    Rq(Cnt).UserData1 = 100
    ' StartIndex Zielspeicher
    Cnt += 1


    Rq(Cnt).Timer(CChar("T"), 0, 1, 10, m_DWordBuf(200))
    ' T0 10 Timer
    Rq(Cnt).UserData0 = MyDataType.DWord
    '
    Rq(Cnt).UserData1 = 200
    ' StartIndex Zielspeicher
    Cnt += 1

    m_Err = Plc.RdMultiBuffered(Rq, CUInt(Cnt))

    ' nun Daten in den Applikatiopnsspeicher holen
    Cnt = 0

    ' lese ab E 4.0 32 Bit
    Rq(Cnt).GetData(m_ByteBuf)
    Cnt += 1

    ' EB0 20 Byte
    Rq(Cnt).GetData(m_ByteBuf(40))
    Cnt += 1

    ' EB 20 1 Wort
    Rq(Cnt).GetData(m_WordBuf(0))
    Cnt += 1

    ' DB10.DW 0 150 Worte
    Rq(Cnt).GetData(m_WordBuf(10))
    Cnt += 1

    ' EB 0 20 Byte in Realbuffer lesen
    Rq(Cnt).GetData(m_WordBuf(250))
    Cnt += 1

    ' DB10.DBB0 60 Realwerte
    Rq(Cnt).GetData(m_DoubleBuf(0))
    Cnt += 1

    ' D10 DBB 200 20 Doppelworte
    Rq(Cnt).GetData(m_DWordBuf(0))
    Cnt += 1

    ' DB10 DB77 50 Doppelworte
    Rq(Cnt).GetData(m_DWordBuf(20))
    Cnt += 1

    ' T5 10 Timer
    Rq(Cnt).GetData(m_DWordBuf(100))
    Cnt += 1

    ' T0 10 Timer
    Rq(Cnt).GetData(m_DWordBuf(200))
    Cnt += 1

    BeginDataListUpdate()
    For i As Integer = 0 To Cnt - 1
      AddDataToList(Rq(i))
    Next
    EndDataListUpdate()
  End Sub


  Private Sub BeginDataListUpdate()
    listData.BeginUpdate()
    listData.Items.Clear()
  End Sub

  Private Sub EndDataListUpdate()
    listData.EndUpdate()
  End Sub

  Private Sub AddDataToList(ByVal Rq As IPS7RdMulti)
    Dim i As Integer
    Dim [Step] As Integer
    Dim SAddr As String
    Dim Count As Integer = Rq.Cnt
    Dim StartAt As Integer = Rq.Start
    Dim BufIdx As Integer = Rq.UserData1
    Dim DataType As Integer = Rq.UserData0
    Dim DataArea As Integer = Rq.DataArea

    If m_Err >= 0 Then
      SAddr = GetAddrName(DataType, ChrW(Rq.DataArea), CUInt(Rq.DBNr))

      If DataType = MyDataType.Bit Then
        Dim BitNr As Integer = Rq.StartBit
        Dim ByteNr As Integer = Rq.Start

        i = 0
        While i < CInt(Count)
          Dim C1 As Char
          Dim S As String


          Dim liv As ListViewItem = listData.Items.Add(SAddr + String.Format("{0}.{1}", ByteNr, BitNr))
          If Rq.Result = 0 Then
            liv.SubItems.Add(String.Format("{0:D}", m_ByteBuf(BufIdx)))
            liv.SubItems.Add(String.Format("0x{0:X2}", m_ByteBuf(BufIdx)))
            C1 = CChar(ChrW(m_ByteBuf(BufIdx)))
            S = String.Format("'{0}'", If(C1 <> ControlChars.NullChar, C1, " "c))
          Else
            S = GetResultString(Rq.Result)
          End If
          liv.SubItems.Add(S)
          If System.Threading.Interlocked.Increment(BitNr) > 7 Then
            BitNr = 0
            ByteNr += 1
          End If
          i += 1
          BufIdx += 1
        End While
      ElseIf DataType = MyDataType.[Byte] Then
        i = 0
        While i < CInt(Count)
          Dim C1 As Char
          Dim S As String
          Dim liv As ListViewItem = listData.Items.Add(SAddr + String.Format("{0}", StartAt + i))

          If Rq.Result = 0 Then
            liv.SubItems.Add(String.Format("{0:D}", m_ByteBuf(BufIdx)))
            liv.SubItems.Add(String.Format("0x{0:X2}", m_ByteBuf(BufIdx)))

            C1 = System.Convert.ToChar(m_ByteBuf(BufIdx))
            S = String.Format("'{0}'", If(C1 <> ControlChars.NullChar, C1, " "c))
            liv.SubItems.Add(S)
          Else
            S = GetResultString(Rq.Result)
          End If
          i += 1
          BufIdx += 1
        End While
      ElseIf DataType = MyDataType.Word Then
        ' Word
        [Step] = 2
        i = 0
        While i < Count
          Dim C1 As Char, C2 As Char
          Dim S As String
          Dim liv As ListViewItem = listData.Items.Add(SAddr + String.Format("{0}", StartAt + i * [Step]))

          If Rq.Result = 0 Then
            liv.SubItems.Add(String.Format("{0:D}", m_WordBuf(BufIdx)))
            liv.SubItems.Add(String.Format("0x{0:X4}", m_WordBuf(BufIdx)))

            C1 = System.Convert.ToChar(m_WordBuf(BufIdx) And &HFF)
            C2 = System.Convert.ToChar(m_WordBuf(BufIdx) >> 8)
            'S = "'" + C2.ToString() + C1.ToString() + "'";
            S = String.Format("'{0}{1}'", If(C2 <> ControlChars.NullChar, C2, " "c), If(C1 <> ControlChars.NullChar, C1, " "c))
          Else
            S = GetResultString(Rq.Result)
          End If

          liv.SubItems.Add(S)
          i += 1
          BufIdx += 1
        End While
      ElseIf DataType = MyDataType.Real Then
        ' Real
        If ChrW(DataArea) = "T" OrElse ChrW(DataArea) = "Z" Then
          [Step] = 1
        Else
          [Step] = 4
        End If
        i = 0
        While i < Count
          Dim liv As ListViewItem = listData.Items.Add(SAddr + String.Format("{0}", StartAt + i * [Step]))

          If Rq.Result = 0 Then
            liv.SubItems.Add(String.Format("{0:F}", m_DoubleBuf(BufIdx)))
          Else
            liv.SubItems.Add(String.Format("{0}", GetResultString(Rq.Result)))
          End If
          i += 1
          BufIdx += 1
        End While
      ElseIf DataType = MyDataType.DWord Then
        ' DWord
        If ChrW(DataArea) = "T" OrElse ChrW(DataArea) = "Z" Then
          [Step] = 1
        Else
          [Step] = 4
        End If
        i = 0
        While i < Count
          Dim C1 As Char, C2 As Char, C3 As Char, C4 As Char
          Dim S As String

          Dim liv As ListViewItem = listData.Items.Add(SAddr + String.Format("{0}", StartAt + i * [Step]))

          If Rq.Result = 0 Then
            liv.SubItems.Add(String.Format("{0:D}", m_DWordBuf(BufIdx)))
            liv.SubItems.Add(String.Format("0x{0:X8}", m_DWordBuf(BufIdx)))

            C1 = System.Convert.ToChar(m_WordBuf(BufIdx) And &HFF)
            C2 = System.Convert.ToChar(m_WordBuf(BufIdx) >> 8 And &HFF)
            C3 = System.Convert.ToChar(m_WordBuf(BufIdx) >> 16 And &HFF)
            C4 = System.Convert.ToChar(m_WordBuf(BufIdx) >> 24 And &HFF)

            'S = "'" + C2.ToString() + C1.ToString() + "'";
            S = String.Format("'{0}{1}{2}{3}'", If(C4 <> ControlChars.NullChar, C4, " "c), If(C3 <> ControlChars.NullChar, C3, " "c), If(C2 <> ControlChars.NullChar, C2, " "c), If(C1 <> ControlChars.NullChar, C1, " "c))
          Else
            S = GetResultString(Rq.Result)
          End If
          liv.SubItems.Add(S)
          i += 1
          BufIdx += 1
        End While
      End If
    End If
  End Sub

  Private Sub StatusTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles StatusTimer.Tick
    Me.StatusTimer.Stop()
    Dim bConnected As Boolean = False
    If m_bOpened AndAlso Plc.GetConnectStatus() = 1 Then
      bConnected = True
    End If
    If bConnected <> m_bConnected Then
      m_bConnected = bConnected
      ShowConnectStatus()
    End If
    Me.StatusTimer.Start()
  End Sub

  Private Sub ShowConnectStatus()
    If m_bConnected Then
      ConnectStatus.Text = "verbunden / connected"
      ConnectStatus.BackColor = Color.LightGreen
    Else
      ConnectStatus.Text = "nicht verbunden / not connected"
      ConnectStatus.BackColor = Color.LightPink
    End If
  End Sub

  Private Sub btnConnect_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnConnect.Click
    If m_bOpened Then
      If Plc.Connect() = 1 Then
        m_bConnected = True
      Else
        m_bConnected = False
      End If
    End If
    ShowConnectStatus()
  End Sub

  Private Sub btnHelp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHelp.Click
    Help.ShowHelp(Me, "ips7lnk.chm")
  End Sub


  Protected Overrides Sub Finalize()
    MyBase.Finalize()
  End Sub

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

  End Sub
End Class




