`

z转载:Mc3000开发培训(vb.net智能终端无线系统开发)

阅读更多


  无线终端开发培训文档
项目名称

Mc3000开发培训(vb.net智能终端无线系统开发)

项目号




项目阶段



日期

2006.9.20


工作要素

培训时间

16:00


培训人员

广州雄冠条码公司


培训程序

开发环境的培训


培训主要内容


智能终端无线系统的开发,起核心部分可以分为这么四类:开发环境,扫描头的处理,服务器和客户端的数据通讯(socket的建立)。

开发环境:

     在这里我们采用的是vb.net2003的开发语言,这种开发语言的特点是简单、界面比较友好、比较容易上手等优点。

下面我们开始正式讲解我们终端程序的开发。

开始项目(如下图所示)

当我们打开vs.net的界面时,出现的界面都是平常开发pc端程序界面是一样的,当我们新建一个项目时,我们就可以选择创建智能终端项目,如下图所示:

我们在上面选择好项目路径和输入一个项目名称,点确定以后系统会要求选择一个针对智能终端的开发平台,如下图所示:

这里我们针对我们所开发的智能终端的操作系统而定,因为智能一般都有pocket pc 和windows ce这两种操作系统,我们现在开发的智能终端mc3000是基于windows ce操作系统的,所以我们选择的开发平台是windows ce。按确定以后就是进到我们正式架构这个项目时候了,如下图:

这里和我们平常开发的场景没有什么两样。

一般的项目开发我们都会采用form by form的方式去架构整个项目,但是对于智能终端项目架构方面按照我们公司的习惯,我们是采用panel by panel方式的,这样做的好处就是减少调用form时终端消耗的内存,因为我们知道一般的终端设备的内存是很小的。

下面我们通过我们公司做过的一个实例来讲解具体的架构方面的东西,如下图所示:

这里我们是把以前form上的东西全部转到panel上面,一个模块一个panel。在系统启动的时候我们先初始化这些panel,所谓初始化就是我们会把form上面的全部panel叠放在一个位置上面,当要调用的时候我们就把相应的panel显示在最上层就ok了。下面我们具体讲一下这些初始化函数:

1、  初始函数InitPanel,这个函数的作用就是把全部的panel事先放在一个合适的位置。如下

    Private Sub InitPanel()

        Dim p As New Point(10, 10)

        Pl_logon.Location = p

        Pl_main.Location = p

        Pl_allsheet.Location = p

        Pl_out.Location = p

End Sub

我们把这些panel都放在终端屏幕x坐标和y坐标都是10的位置上

2、  成员函数EnumPanel,我们利用这个函数定义一些相应的panel成员;

    Private Enum EnumPanel

        ScanLoginpanel

        ScanmainPanel

        ScanoutPanel

        ScansheetPanel

    End Enum

3、  调用panel函数ShowPanel(ByVal pPanel As EnumPanel),我们利用这个函数调用相应的panel。

    Private Sub ShowPanel(ByVal pPanel As EnumPanel)

        Select Case pPanel

            Case EnumPanel.ScanLoginpanel

                Me.Text = "登录"

                Pl_logon.BringToFront()

            Case EnumPanel.ScanmainPanel

                Me.Text = "主目录"

                Pl_main.BringToFront()

                Pl_main.Focus()

            Case EnumPanel.ScanoutPanel

                Me.Text = "出货"

                Pl_out.BringToFront()

            Case EnumPanel.ScansheetPanel

                Me.Text = "配货单列表"

                Pl_allsheet.BringToFront()

        End Select

    End Sub

到这里我们就把终端开发的架构讲完,相信大家也已经理解了这种架构的开发。我们接下来开始讲扫描头的处理方面的东西。

扫描头的处理:

作为数据采集终端,扫描头的处理在整个项目是非常重要的,因为它是数据来源。基本上每款终端,厂家一般都会提供处理的扫描头的dll,同样symbol公司也提供这样的dll--SMDK-M-1.01.06.exe,在项目开发之前我们要先这个dll安装上去,安装上去以后我们才能调用它的扫描头处理的相关函数。安装成功以后,我们要在项目上引用这个dll,如下图:

这上面那些引用都是我们要用到的dll,第三个symbol.barcode就是关于扫描头。引用完成我们就可以在我们的项目上处理我们的扫描头了。我们先创建一些关于扫描头的对象

    Private myreader As Symbol.Barcode.Reader = Nothing

    Private myreaderData As Symbol.Barcode.ReaderData = Nothing

    Private myreadnotifyhander As System.EventHandler = Nothing

Private myStatusNotifyHandler As System.EventHandler = Nothing

上面那些就是扫描头的对象。下面我们具体来讲解一下这些关于扫描头的函数:

1、   扫描头初始化函数Private Function InitRead(),这个函数我们具体在代码。

2、  开启扫描头函数Private Sub StartRead()和Private Sub StartStatus()

3、  关闭扫描头函数Private Sub StopRead()和Private Sub StopStatus()

4、  数据采集函数   Private Sub HandleData(ByVal TheReaderData As Symbol.Barcode.ReaderData),我们这里具体讲一下这个函数:

    Private Sub HandleData(ByVal TheReaderData As Symbol.Barcode.ReaderData)

        Dim filestr As String

        ScanData = TheReaderData.Text

        If Trim(ScanData).Length = 10 Then

            tb_outbox.Text = ScanData

            Me.StartStatus()

            Me.StartRead()

        ElseIf (Trim(ScanData).Length = 19) Or (Trim(ScanData).Length = 22) Then

            If tb_outsheet.Text <> "" Then

                If tb_outbox.Text <> "" Then

                    tb_outbcr.Text = ScanData

                    SendCommand("updateoutinfo" & "|" & Trim(tb_outsheet.Text) & "|" & Trim(tb_outbox.Text) & "|" & Trim(tb_outbcr.Text))

                    Me.StopRead()

                    Me.StopStatus()

                Else

                    P(500, 3000)

                    P(500, 3000)

                    P(500, 3000)

                    'MsgBox("请先扫描或者输入箱号")

                    Lb_message.ForeColor = Color.Red

                    Lb_message.Text = "请先扫描或者输入箱号"

                    tb_outbox.Focus()

                End If

            Else

                P(500, 3000)

                P(500, 3000)

                P(500, 3000)

                'MsgBox("请先输入配货单号")

                Lb_message.ForeColor = Color.Red

                Lb_message.Text = "请先输入配货单号"

                tb_outsheet.Focus()

            End If

        Else

            'MsgBox("请扫描正确条码")

            Lb_message.ForeColor = Color.Red

            Lb_message.Text = "请扫描正确条码"

            Me.StartStatus()

            Me.StartRead()

        End If

End Sub

我们扫描头处理就先讲到这里,顺便我们讲一下声音的处理,声音处理对于数据采集终端来说也是很重要的,它可以起到警示的作用。要用声音我们也要先引用symbol.audio。

先创建一个声音对象    Private MyAudioController As Symbol.Audio.Controller = Nothing

具体的函数,有两个声音函数

1、   P(ByVal pD As Integer, ByVal pF As Integer)

2、   P(ByVal pD As Integer, ByVal pF As Integer, ByVal pFN As String)



服务器和客户端的数据通讯

服务器和客户端的数据通讯分两部分,我们先讲客户端这部分,然后讲服务器端。

客户端

在客户端我们首先会去设置一个服务器的ip地址和端口。用文本文件保存在本地,然后用函数去调用这个文件得到ip地址和端口。当程序启动的时候我们去连接服务器端。函数是Private Function Connect() As Boolean,这个函数是要到socket,所以我们首先Imports System.Net.Sockets。下面我们看一下Connect()函数:

    Private Function Connect() As Boolean

        Try

            tpcClient = New TcpClient

            tpcClient.Connect(System.Net.IPAddress.Parse(strIP), strPort)

            tpcClient.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf DoRead, Nothing)

            Return True

        Catch ex As Exception

            MsgBox("服务器未启动或设置不正确,无法连接到服务器。", MsgBoxStyle.Critical)

            Return False

        End Try

    End Function

我们定义tpcClient这个客户端的socket对象,然后通过这个对象去连接服务器,并且利用一个doread函数去读取和服务器交互的数据流。下面我来看一下这个doread函数

    Private Sub DoRead(ByVal ar As IAsyncResult)

        Dim BytesRead As Integer

        Dim strMessage As String

        If blnExit Then

            Exit Sub

        End If

        Try

            ' Finish asynchronous read into readBuffer and return number of bytes read.

            BytesRead = tpcClient.GetStream.EndRead(ar)

            If BytesRead < 1 Then

                ' If no bytes were read server has close.  Disable input window.

                'MarkAsDisconnected()

                Exit Sub

            End If

            ' Convert the byte array the message was saved into, minus two for the

            ' Chr(13) and Chr(10)

            strMessage = Encoding.Unicode.GetString(readBuffer, 0, BytesRead - 2)

            ProcessCommands(strMessage)

            ' Start a new asynchronous read into readBuffer.

            tpcClient.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf DoRead, Nothing)

        Catch e As Exception

            'MarkAsDisconnected()

            'MsgBox(e.ToString, MsgBoxStyle.Critical, "Error in DoRead")

        End Try

    End Sub

在这个函数里我们会把读到的数据流转换成字符串,并且不停的去贞听缓冲区的数据,当成功的得到数据时,我们利用这个ProcessCommands(strMessage)函数进行处理,得到我们需要的结果。

    Private Sub ProcessCommands(ByVal strMessage As String)

        Dim ary() As String

        Dim aryCmd() As String

        Dim filestr As String

        Try

            If strMessage.Length > 0 Then

                aryCmd = strMessage.Split(END_CHAR)

                'bcruse = True

                Dim i As Integer

                If aryCmd.Length >= 1 Then

                    For i = 0 To aryCmd.Length - 1

                        If aryCmd(i) <> "" Then

                            Dim intPos As Integer

                            Dim strResult As String = aryCmd(i)

                            Debug.WriteLine(strResult)

                            intPos = aryCmd(i).ToUpper.IndexOf(CMD_Pre)

                            If intPos < 0 Then

                                strResult = ""

                            Else

                                strResult = aryCmd(i).Substring(intPos + CMD_Pre.Length)

                                If strResult.Substring(strResult.Length - 1) = END_CHAR Then

                                    strResult = strResult.Substring(0, strResult.Length - 1)

                                End If

                            End If

                            ary = strResult.Split(Chr(124))

                            Select Case ary(0).ToUpper

                                Case "notbcrtobill".ToUpper

                                    P(500, 3000)

                                    P(500, 3000)

                                    P(500, 3000)

                                    'MsgBox("此单号不包含此条码")

                                    Lb_message.ForeColor = Color.Red

                                    Lb_message.Text = "此单号不包含此条码"

                                    tb_outbcr.ForeColor = Color.Red

                                    Me.StopRead()

                                    Me.StopStatus()

                                    Me.StartStatus()

                                    Me.StartRead()

                            End Select

                        End If

                    Next

                End If

            End If

        Catch ex As Exception



        End Try

    End Sub

这个函数我们就会把从缓冲区得到的字符串解成我们需要的信息,并这些信息显示在相应的模块里,也给客户提供相应的提示。上面讲的都是怎样从服务器端得到数据,下面我们讲一下怎么向服务器端发送数据。因为我们这个扫描采集数据的,所以当我们扫描得到数据时,我们就会向服务器端发送数据,这个函数SendCommand("updateoutinfo" & "|" & Trim(tb_outsheet.Text) & "|" & Trim(tb_outbox.Text) & "|" & Trim(tb_outbcr.Text))就是向服务器端发送数据的,大家注意到我们会把要发送的数据生成一个字符串,字符串前面的"updateoutinfo"是个自己定义的命令头,后面的就是具体的数据,中间是用“|”分割,这些开发时都是可以自己灵活处理,下面我们看一下这个发送函数

    Private Sub SendCommand(ByVal pInput As String)

        SendData(CMD_Pre & pInput & END_CHAR)

    End Sub

    Public Sub SendData(ByVal data As String)

        Try

            Dim writer As New IO.StreamWriter(tpcClient.GetStream, Encoding.Unicode)

            writer.Write(data & END_CHAR)

            writer.Flush()

        Catch ex As Exception

        End Try

    End Sub

这个就是数据写到缓冲区。

看完客户端,下面接着让我们来看看服务器端的数据处理。

服务器端


服务器端我们会连接数据库进行数据。程序启动以后我们首先会设置数据库的连接,上面的服务器就是数据库所在的ip地址,用户名就是数据库的sa,密码就是sa的密码。数据库处理我们需要引用一个dll

Imports DataAccess。

服务器端启动以后,系统会先启动socket连接,函数StartServer()。

    Private Sub StartServer()

        '取得端口号

        PORT_NUM = GetPortNum()

        listenerThread = New Threading.Thread(AddressOf DoListen)

        listenerThread.Start()

        UpdateStatus("无线监听已启动。")

End Sub

在这个函数我们使用线程技术,就是每个终端连接到,服务器都会用一个线程去处理。这样就可以同时处理多个终端的数据请求。DoListen函数就是贞听来自终端的数据。

    Private Sub DoListen()

        Try

            ' Listen for new connections.

            listener = New TcpListener(System.Net.IPAddress.Any, PORT_NUM)

            listener.Start()

            Do

                ' Create a new user connection using TcpClient returned by

                ' TcpListener.AcceptTcpClient()

                Dim client As New UserConnection(listener.AcceptTcpClient)

                ' Create an event handler to allow the UserConnection to communicate

                ' with the window.

                AddHandler client.LineReceived, AddressOf OnLineReceived

                UpdateStatus("New connection found: waiting for log-in")

            Loop Until False

        Catch ex As Exception

            If listener Is Nothing Then

            Else

                listener.Stop()

            End If

            If blnExit Then

            Else

                Me.StartServer()

            End If

            SaveLog("DoListen", ex.ToString)

        End Try

    End Sub

这个AddHandler client.LineReceived, AddressOf OnLineReceived就是做了一个模块去处理接受数据,client.LineReceived是从缓冲区接收数据,OnLineReceive是对接收到的数据进行处理。数据处理的原理和客户端的数据处理一样,但是这里会把数据和数据库进行交互,具体的看源代码来解释。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics