天天看點

移植Vb程式到mobile

   Windows CE現在在嵌入式系統應用已經很多了,以前使用EVC的開發多些,開發難度大周期長。VS2005退出後,CF.net2.0對于VB.NET支援很好,使将原來的基于windows平台的Visual Basic維護程式移植到CE上面提供呢可能,本文将就Visual Basic維護程式移植到CE上面做一個試驗性質的開發。

   Visual Basic因為其界面開發快速,掌握難度低,在嵌入式系統的程式員中應用很廣,比如說本人,以前經常做些單片機的開發,那麼一些系統參數或規約的驗證,就會随手寫個Visual Basic程式驗證下,以前是VB6.0,後來VB.net多些,VB的開發擴充性好,做界面簡單快速,而且友善在調試中修改程式,在驗證單片機的程式時是再友善不過了。

   最早的人機界面、維護參數基本是通過序列槽通訊,在計算機或便攜筆記本上面顯示,設定。随着嵌入式系統發展,使用者要求越來越高,現在好多的裝置上面要有顯示參數和狀态的液晶,對于一些高檔裝置,更是需要複雜的使用者界面,如果能将裝置的維護和狀态顯示程式移植到基于Windows CE的系統平台上面去,就會提供快速的軟體開發,使用者界面會更加美觀,開發速度大幅提供,友善嵌入式系統工程師的開發工作,同時基于windows CE的PDA掌上電腦,友善攜帶,待機時間更加長,友善現場維護人員和分布式系統的設定和分析工作。

   講原有的VB.net移植到winCE,比較簡單,如果沒有使用第三方的windows平台的控件,可以很簡單的移植過去,窗體可以很簡單的複制過去,代碼基本是可以複用的,如果是VB6的程式,移植的難度會大些,窗體部分設計需要重新設定,VB.net的窗體界面和VB的差別很大,可以先按照老的程式的界面設定,在新的程式裡面設定,代碼方面的移植難度不大,基本的語句還是一樣的,VB.NET支援界面上的元素可以全新建立,不用想VB那樣,從視窗的控件數組裡面派生了,而且vb.net可以在運作中定義事件的處理函數,這個對VB是很大的改進,是自動根據規約或界面設定進行處理變得友善快捷。

   對于嵌入式系統來說和外界的通訊主要有幾個方面,序列槽(RS485、RS232),網絡。網絡方面的程式差別不是很大,序列槽方面,windows下面VB程式員一般是使用MSCOMM來進行通訊,微軟在CF.NET2.0裡面提供了新的序列槽開發支援SerialPort,比1.0和EVC更加快速。另外VB.NET支援多線程,使序列槽開發變得容易。

   下面提供一個我自己實作的序列槽多線程類。

Imports System.IO.Ports

Imports System.Threading

'232序列槽操作類

'2006 6 20 V1.0  by 趙力钊

'使用說明

'使用前調用 Init 退出程式或關閉序列槽使用 Close

'SendDate 發送資料到序列槽 傳回發送成功與否

'判斷ComStatus 是否為2 資料是否準備好 準備好 調用 ReadData 傳空的BYTE數組(可以Redim的),傳回資料長度

Public Class RS232TXClass

    Shared m_SerialPort As New SerialPort

    Shared readThread As Thread = New Thread(AddressOf Read)

    Public ComSetting As String     '"9600,n,8,1"

    Public ComPort As Integer

    Public ComType As Integer        '硬體設定

    Dim strBaudRate As String

    Dim Parity As String

    Dim Handshake As Integer

    Dim DataBits As Integer

    Dim PortName As String

    Dim StopBits As Integer

    Shared _continue As Boolean

    Shared bRxLock As Boolean

    Shared iRxLen As Integer

    Shared iRxTime As Integer

    Shared bRxStatus As Byte

    Const READOK = 2

    Const READOUTTIME = 4

    Const READLOCK = 8

    Const COMOK = 1

    Const COMERROR = 0

    Const COMFREE = 16

    '輸入函數 setting 序列槽設定如 9600,n,8,1  Type 握手協定 0 沒有握手協定 Port 序列槽号

    Public Sub Init(ByVal Setting As String, ByVal Type As Integer, ByVal Port As Integer)

        ComSetting = Setting

        ComPort = Port

        ComType = Type

        ComInit()

    End Sub

    Sub ComInit()

        Dim iStart As Integer

        Dim iTemp As Integer

        Dim bDate() As Byte

        m_SerialPort = New System.IO.Ports.SerialPort()

        iStart = InStr(1, ComSetting, ",")

        strBaudRate = Mid(ComSetting, 1, iStart - 1)

        iTemp = InStr(iStart + 1, ComSetting, ",")

        Parity = Mid(ComSetting, iStart + 1, iTemp - iStart - 1)

        iStart = iTemp + 1

        iTemp = InStr(iStart, ComSetting, ",")

        DataBits = CInt(Mid(ComSetting, iStart, iTemp - iStart))

        iStart = iTemp + 1

        StopBits = CInt(Mid(ComSetting, iStart, Len(ComSetting) - iStart + 1))

        m_SerialPort.BaudRate = strBaudRate

        Select Case Parity

            Case "n"

                m_SerialPort.Parity = IO.Ports.Parity.None

            Case "N"

                m_SerialPort.Parity = IO.Ports.Parity.None

            Case "e"

                m_SerialPort.Parity = IO.Ports.Parity.Even

            Case "E"

                m_SerialPort.Parity = IO.Ports.Parity.Even

            Case "o"

                m_SerialPort.Parity = IO.Ports.Parity.Odd

            Case "O"

                m_SerialPort.Parity = IO.Ports.Parity.Odd

        End Select

        m_SerialPort.DataBits = DataBits

        Select Case StopBits

            Case 0

                m_SerialPort.StopBits = IO.Ports.StopBits.None

            Case 1

                m_SerialPort.StopBits = IO.Ports.StopBits.One

            Case 2

                m_SerialPort.StopBits = IO.Ports.StopBits.Two

        End Select

        Select Case ComType

            Case 0

                m_SerialPort.Handshake = IO.Ports.Handshake.None

            Case 1

                m_SerialPort.Handshake = IO.Ports.Handshake.RequestToSend

            Case 2

                m_SerialPort.Handshake = IO.Ports.Handshake.RequestToSendXOnXOff

            Case 3

                m_SerialPort.Handshake = IO.Ports.Handshake.XOnXOff

        End Select

        m_SerialPort.PortName = "COM" + CStr(ComPort)

        m_SerialPort.ReadTimeout = 500

        m_SerialPort.WriteTimeout = 500

        If m_SerialPort.IsOpen = True Then

            m_SerialPort.Close()

        End If

        m_SerialPort.Open()

        If m_SerialPort.IsOpen = True Then

            bRxStatus = COMOK

            ReDim bDate(2)

            ReadData(bDate)

            bRxLock = False

            readThread.Start()

        Else

            bRxStatus = COMERROR

        End If

        ' readThread.Join()

    End Sub

    Public Function ComStatus() As Byte

        ComStatus = bRxStatus

    End Function

    Function ReadData(ByRef bDate() As Byte) As Integer

        Dim bLen As Integer

        bLen = m_SerialPort.BytesToRead

        If bLen > 0 Then

            ReDim bDate(bLen)

            m_SerialPort.Read(bDate, 0, bLen)

            ReadData = bLen

        Else

            ReadData = 0

        End If

        bRxStatus = COMFREE

    End Function

    Public Function SendDate(ByVal bDateBuff() As Byte, ByVal iLen As Integer) As Boolean

        If bRxLock = False Then

            m_SerialPort.Write(bDateBuff, 0, iLen)

            bRxLock = True

            bRxStatus = READLOCK

            SendDate = True

        Else

            SendDate = False

        End If

    End Function

    Public Shared Sub Read()

        While (1)

            Thread.Sleep(50)

            Try

                If m_SerialPort.BytesToRead <> iRxLen Then

                    iRxLen = m_SerialPort.BytesToRead

                    iRxTime = 0

                    bRxStatus = READLOCK

                Else

                    If iRxLen > 0 Then

                        '收到資料

                        bRxStatus = READOK

                        bRxLock = False

                    Else

                        iRxTime = iRxTime + 1

                        If iRxTime > 10 Then

                            bRxStatus = READOUTTIME

                        End If

                        bRxLock = False

                    End If

                End If

            Catch ex As TimeoutException

                ' Do nothing

            End Try

        End While

    End Sub

    Public Sub Close()

        readThread.Abort()

        m_SerialPort.Close()

    End Sub

End Class

定義視窗變量

 Dim ComPort As New RS232TXClass

啟動後調用

ComPort.Init("9600,n,8,1", 0, 1)

在主視窗中,通過一個定時器事件,檢視序列槽情況

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Dim bDate() As Byte

        Dim iLen As Integer

        ReDim bDate(2)

        If ComPort.ComStatus = 2 Then

            iLen = ComPort.ReadData(bDate)

            If iLen > 2 Then

                ShowRevDate(bDate, iLen)

            End If

        End If

    End Sub

   下面實作一個windows的路燈維護程式移植到windows CE上面去的一些簡單示例。

   這是原來VB上面的一個界面。

<img src=https://p-blog.csdn.net/images/p_blog_csdn_net/zhao74/EntryImages/20080722/1.JPG></img>

   這個是我移植到VB.net for Mobile的版本,因為在Mobile上面多視窗切換很麻煩,就作成分頁的顯示了。

   <img src=https://p-blog.csdn.net/images/p_blog_csdn_net/zhao74/EntryImages/20080722/2.JPG></img>

   需要注意的是,因為Mobile上面的輸入法啟動後會遮蓋一部分視窗,為了輸入方面最後把需要輸入的地方放到上面去,以免影響輸入。這裡我把兩個顯示性Label放到了後面。

   VB.NET的繪圖和VB不是很一樣,更加接近C++的繪圖方式,但是隻要不一些概念弄清楚,你會發現這種繪圖方式使用更加友善,更加友善你對于GDI+的了解。

   VB.NET中可以使用 Dim bm As New Bitmap(238, 214) 直接建立一個位圖,然後把繪制好的位圖覆寫回去。

   繪制文字的時候,需要字型和畫刷,象下面這樣:

    ShowTextBrush = New SolidBrush(Color.Blue)

    mFont = New Font(FontFamily.GenericSansSerif, 8, FontStyle.Regular)

    g.DrawString("HELLO", mFont, ShowTextBrush, 12, 82)

   繪制線的時候,需要畫筆。

     Pen1 = New Pen(Color.Red)

     g.DrawLine(Pen1, OldX, OldY, NewX, NewY)

   填充圖形的時候,需要畫刷

   tempbrush = New SolidBrush(Color.FromArgb(192, 192, 255))

   g.FillRectangle(tempbrush, 0, 0, 238, 214)

   繪制扇形和弧形,VB.NET沒有提供,但是我從網上找到了實作方法,用聯系線和連續填充實作弧形和棒圖的繪制。函數如下

   '=====================================================

    '繪制弧形

    '

    '    graphicsObject - Graphics 對象

    '    pen            - 畫筆

    '    x,y            - 弧的圓心

    '    width          - 寬度 (X直徑)

    '    height         - 高度 (Y直徑)

    '    startAngle     - 起始角度

    '    sweepAngle     - 結束角度

    '

    Private Sub drawPie(ByVal graphicsObject As Graphics, ByVal pen As Pen, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal startAngle As Single, ByVal sweepAngle As Single)

        Dim xAngle(12) As Single

        Dim yAngle(12) As Single

        Dim angleIncrement As Single

        angleIncrement = (sweepAngle - startAngle) / 10

        Dim angle As Single

        angle = startAngle

        Dim i As Integer

        For i = 0 To 10

            xAngle(i) = x + (Math.Cos(angle * (Math.PI / 180)) * (width / 2))

            yAngle(i) = y + (Math.Sin(angle * (Math.PI / 180)) * (height / 2))

            angle += angleIncrement

        Next i

        xAngle(11) = x + (Math.Cos(sweepAngle * (Math.PI / 180)) * (width / 2))

        yAngle(11) = y + (Math.Sin(sweepAngle * (Math.PI / 180)) * (height / 2))

        Dim anglePoints(12) As Point

        anglePoints(0) = New Point(x, y)

        For i = 0 To 11

            anglePoints(i + 1) = New Point(CInt(xAngle(i)), CInt(yAngle(i)))

        Next

        graphicsObject.DrawPolygon(pen, anglePoints)

    End Sub

    '=====================================================

    '填充弧形

    '    graphicsObject - Graphics 對象

    '    solidBrush     - 畫刷

    '    x,y            - 弧的圓心

    '    width          - 寬度 (X直徑)

    '    height         - 高度 (Y直徑)

    '    startAngle     - 起始角度

    '    sweepAngle     - 結束角度

    '

    Sub fillPie(ByVal graphicsObject As Graphics, ByVal solidBrush As SolidBrush, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal startAngle As Single, ByVal sweepAngle As Single)

        Dim xAngle(12) As Single

        Dim yAngle(12) As Single

        Dim angleIncrement As Single

        angleIncrement = (sweepAngle - startAngle) / 10

        Dim angle As Single

        angle = startAngle

        Dim i As Integer

        For i = 0 To 10

            xAngle(i) = x + (Math.Cos(angle * (Math.PI / 180)) * (width / 2))

            yAngle(i) = y + (Math.Sin(angle * (Math.PI / 180)) * (height / 2))

            angle += angleIncrement

        Next i

        xAngle(11) = x + (Math.Cos(sweepAngle * (Math.PI / 180)) * (width / 2))

        yAngle(11) = y + (Math.Sin(sweepAngle * (Math.PI / 180)) * (height / 2))

        Dim anglePoints(12) As Point

        anglePoints(0) = New Point(x, y)

        For i = 0 To 11

            anglePoints(i + 1) = New Point(CInt(xAngle(i)), CInt(yAngle(i)))

        Next

        graphicsObject.FillPolygon(solidBrush, anglePoints)

    End Sub

繼續閱讀