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スレッドに戻る必要があります。InvokeRequiredUIスレッド以外のスレッドを使用している場合、プロパティはtrueを返し、メソッドはUIスレッドから指定されたメソッドInvokeを呼び出します。

于 2012-10-11T13:38:33.360 に答える