1

我正在开发一个从串行端口(COMM 端口)读取内容的应用程序。简而言之,它的工作原理是这样的:当您在酒吧或餐厅工作时,您必须先扫描一张卡片,然后才能在收银机中输入内容。如果这张卡返回一个好的数字,你可以输入一些东西。

因此,必须有一个表单来监听串口并检查是否有人扫描卡以及是否是具有良好权限的卡。

如果此人具有良好的权利,则可以关闭该表格并调用另一个表格。

现在,在代码中:

在这里,加载了 MenuForm(在读取正确代码后必须可以访问的表单)。我打电话给 frmWaiterKey 来显示。

Private Sub frmMenu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim oForm As frmWaiterKey = New frmWaiterKey()
    oForm.ShowDialog()
End Sub

frmWaiterKey 类的代码:

Private Sub frmWaiterKey_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    nameArray = SerialPort.GetPortNames
    OpenComPort()
    AddHandler myComPort.DataReceived, SerialDataReceivedEventHandler1
End Sub

Sub OpenComPort()

    Try
        ' Get the selected COM port's name 
        ' from the combo box.
        If Not myComPort.IsOpen Then
            myComPort.PortName = _
            nameArray(0).ToString()
            ' Get the selected bit rate from the combo box.
            myComPort.BaudRate = CInt(9600)
            ' Set other port parameters.
            myComPort.Parity = Parity.None
            myComPort.DataBits = 8
            myComPort.StopBits = StopBits.One
            myComPort.Handshake = Handshake.None

            'myComPort.ReadTimeout = 3000
            'myComPort.WriteTimeout = 5000

            ' Open the port.
            myComPort.Open()

        End If

    Catch ex As InvalidOperationException
        MessageBox.Show(ex.Message)
    Catch ex As UnauthorizedAccessException
        MessageBox.Show(ex.Message)
    Catch ex As System.IO.IOException
        MessageBox.Show(ex.Message)
    End Try

End Sub
Sub CloseComPort()

    Using myComPort
        If (Not (myComPort Is Nothing)) Then
            ' The COM port exists.
            If myComPort.IsOpen Then
                ' Wait for the transmit buffer to empty.
                Do While (myComPort.BytesToWrite > 0)
                Loop
            End If
        End If
    End Using

End Sub

Private SerialDataReceivedEventHandler1 As New SerialDataReceivedEventHandler(AddressOf DataReceived)

' Specify the routine that runs when 
' a DataReceived event occurs at myComPort.

' This routine runs when data arrives at myComPort.

Friend Sub DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
    Dim newReceivedData As String
    ' Get data from the COM port.
    newReceivedData = myComPort.ReadExisting
    newReceivedData = newReceivedData.Trim()
    MsgBox(newReceivedData)
    If newReceivedData.Equals("00150324294764") Then
        CloseComPort()
        Me.Close()
    End If

End Sub

我在最后一行得到一个错误: Me.Close() 我明白了:我从 frmMenu 调用表单 frmWaiterKey 并且无法在此处关闭它......但我不知道如何解决这个问题。

我希望有人可以帮助我或告诉我我做错了什么。

4

1 回答 1

5

首先,您需要创建一个这样的方法:

Private Sub CloseMe()
    If Me.InvokeRequired Then
        Me.Invoke(New MethodInvoker(AddressOf CloseMe))
        Exit Sub
    End If
    Me.Close()
End Sub

然后,通过调用该方法关闭表单,如下所示:

If newReceivedData.Equals("00150324294764") Then
    CloseComPort()
    CloseMe()
End If

这是必要的原因是因为 WinForms 中的所有 UI 活动都必须从同一个线程执行。由于该DataReceived方法是从另一个线程调用的,因此它必须返回到 UI 线程才能关闭表单。InvokeRequired如果您在 UI 线程以外的任何线程上,则该属性返回 true,并且该Invoke方法从 UI 线程调用给定方法。

于 2012-10-11T13:38:33.360 回答