VB6.0 程序升级到 VB 2008 相关问题总结

VB6.0 程序升级到 VB 2008 相关问题总结

VS 20008在很大程度向VB6老程序员做出了让步,使得VB6程序员升级到.net 比以前要容易得多了。许多地方考虑了VB6级的问题,如增加了Microsoft.VisualBasic.Compatibility命名空间,在帮助中详细比较了VB 2008 VB6在各方面的细微差别。VB6中的许多有用函数在VB 2008 中依然可以使用等。在这种情况下,我把我以前用VB6做的一些程序升级到了VB2008 ,下面我把升级过程中遇到的一些问题做一下总结.

一、VB6中允许定义下标不是0的数组,但在VB 2008 中所有的数组下标将全部是0,这将带来很多升级后错误。尤其是一些控件如Listview控件,VB 2008 COM控件直接升级为对应的.net 控件。但升级后控件下标全部变为0,会带来许多错误,升级后代码也很臃肿,需要优化。如升级前代码:

――――――――――――――――――――――――――――

  Dim i As Long

        Dim totalbytes As Double

        Dim itemx As listItem

        For i = 1 To RTUs.Count

            itemx = ListView1.ListItems(i)

            itemx.Text = RTUs(i).RtuName

            itemx.SubItems(1) = Str(RTUs(i).SendoutByteQty)

            itemx.SubItems(2) = Str(RTUs(i).ReceiveByteQty)

            itemx.SubItems(3) = Str(RTUs(i).SendoutByteQty + RTUs(i).ReceiveByteQty)

            totalbytes = totalbytes + RTUs(i).SendoutByteQty + RTUs(i).ReceiveByteQty

        Next i

        txtTotalbytes.Text = totalbytes

――――――――――――――――――――――――――――――――――――

升级后:

Dim i As Integer

         Dim totalbytes As Double

         Dim itemx As System.Windows.Forms.ListViewItem

        For i = 1 To RTUs.Count

            'UPGRADE_WARNING: 集合ListView1.ListItems 的下限已由1 更改为0。单击以获得更多信息:ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="A3B628A0-A810-4AE2-BFA2-9E7A29EB9AD0"

            itemx = ListView1.Items.Item(i)

            itemx.Text = RTUs(i).RtuName

            'UPGRADE_WARNING: 集合itemx 的下限已由1 更改为0。单击以获得更多信息:ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="A3B628A0-A810-4AE2-BFA2-9E7A29EB9AD0"

            If itemx.SubItems.Count > 1 Then

                itemx.SubItems(1).Text = Str(RTUs(i).SendoutByteQty)

            Else

                itemx.SubItems.Insert(1, New System.Windows.Forms.ListViewItem.ListViewSubItem(Nothing, Str(RTUs(i).SendoutByteQty)))

            End If

            'UPGRADE_WARNING: 集合itemx 的下限已由1 更改为0。单击以获得更多信息:ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="A3B628A0-A810-4AE2-BFA2-9E7A29EB9AD0"

            If itemx.SubItems.Count > 2 Then

                itemx.SubItems(2).Text = Str(RTUs(i).ReceiveByteQty)

            Else

                itemx.SubItems.Insert(2, New System.Windows.Forms.ListViewItem.ListViewSubItem(Nothing, Str(RTUs(i).ReceiveByteQty)))

            End If

            'UPGRADE_WARNING: 集合itemx 的下限已由1 更改为0。单击以获得更多信息:ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="A3B628A0-A810-4AE2-BFA2-9E7A29EB9AD0"

            If itemx.SubItems.Count > 3 Then

                itemx.SubItems(3).Text = Str(RTUs(i).SendoutByteQty + RTUs(i).ReceiveByteQty)

            Else

                itemx.SubItems.Insert(3, New System.Windows.Forms.ListViewItem.ListViewSubItem(Nothing, Str(RTUs(i).SendoutByteQty + RTUs(i).ReceiveByteQty)))

            End If

            totalbytes = totalbytes + RTUs(i).SendoutByteQty + RTUs(i).ReceiveByteQty

        Next i

         txtTotalbytes.Text = CStr(totalbytes)

变得很臃肿,而且有错误,首先要把itemx = ListView1.Items.Item(i)

改为     itemx = ListView1.Items.Item(i-1)

然后可以把那些不必要的判断去掉。

变为:

         Dim i As Integer

         Dim totalbytes As Double

         Dim itemx As System.Windows.Forms.ListViewItem

        For i = 1 To RTUs.Count

            itemx = ListView1.Items.Item(i - 1)

            itemx.Text = RTUs(i).RtuName

          itemx.SubItems(1).Text = Str(RTUs(i).SendoutByteQty)

            itemx.SubItems(2).Text = Str(RTUs(i).ReceiveByteQty)

         itemx.SubItems(3).Text = Str(RTUs(i).SendoutByteQty + RTUs(i).ReceiveByteQty)

            totalbytes = totalbytes + RTUs(i).SendoutByteQty + RTUs(i).ReceiveByteQty

        Next i

         txtTotalbytes.Text = CStr(totalbytes)

VB6 升级后的程序中这种错误会很多,但也比较好改,是最简单的也是最多的错误源之一。

二、关于API函数调用。在VB6中有很多API函数的调用(C++编写的DLL),但升级到VB2008 后这些API函数调用就不好用了,也许是调用格式,参数,或语法没搞对吧。我的解决办法是将这些API函数封装成一个COM组件,在.net 中调用。..net COM的支持还是非常强大的。

三、Menu 控件升级后会有错误产生,因为.net menustrip contextmenustrip两个控件来升级VB6中的menu控件的。如原来的AddDB窗体的PopupMenu mnuxxx变为 mnuxxx.show. (Me.AddDB, New Point(e.X, e.Y))

四、如果想手动控制子窗体的大小位置,子窗体升级后行为会发生变化,但仅需改动startposition属性为manual即可。

五、Vs 2008 XML编辑器做得很好。

六、Vs 2008的最可爱之处在于其类关系图,基本上可以算是替代VB6的类生成器插件。可以可视化地设计类的方法属性事件,及类之间的关系。也可做类关系查看的好工具。但现在vs 2008 的最可恨之处也是在这个类关系图,因为只要类关系图开得时间久了,系统的CPU占用率有时就会很快飙升至50%以上,所以不得不把它关了。开始时不知道是类关系图的问题还以为是VS 2008 整体环境的问题呢。希望后面的版本能解决这个问题。

七、有关ADODB的程序代码,vs2008能够做到100%全部正确升级。

八、.net 的对象序列化为XML方法(system.xml.seralizer)和Propertygrid控件能极大简化配置文件和配置界面的开发制作过程。

九、VB6的参数传递默认是按引用传递,vb 2008 却是默认按值传递。会引起一些错误。尤其是在调用COM组件时,如果要接收COM组件内的类的事件,则参数必是按值传递否则会无法接收。

十、Treeview控件升级后会有错误,升级后的控件,是集合层层包含的关系,即每个节点的子节点都是一个独立的集合,而VB6中的却是所有节点在一个集合里。Nodes集合包含的containskey功能是很贴心的功能,在VB6中只好自己编了。

十一、       依然支持在线调试COM组件代码与VB6的调试功能差不多。这是一个非常有用的功能。

十二、       关于控件数组的升级。虽然在Microsoft.VisualBasic.Compatibility命名空间中提供了各种控件的控件数组升级办法,但我还是不想使用控件数组了(我认为那只是权宜之计),所以在升级后还是把所有的升级控件数组改成其它办法实现了。解决控件数组问题可以有多种方法,其中比较好的方法是采用AddHandler 语句和Addressof 语句(即委托)。举例来说winsock控件的应用过程中如果想做多个连接支持的话是必须用控件数组的,那么我怎么来把它升级呢?事实上,在VB 2008 中的TCPlistener TCPClient两个类就是winsock控件升级对应的相应组件。如果想升级以前的代码,而且尽量少改动原来的代码,办法就是用TCPlistener TcpClient两个类来模拟winsock控件而且越像越好。模拟winsock控件的关键就是模拟connectionRequest事件和DataArrival事件。原来在ConnecttionRequest事件中是必须加载新的winsock控件实例才能接收多连接的,所以得用控件数组。现在新的模拟出的connectionRequest事件是在mywinsockListener中自定义的,它传出一个已建立好连接的MywinsockClient对象,只须把这些对象的DataArrival事件指向一个固定的处理函数就行了,这时就要Addhandler语句和Addressof语句(即委托)上场了。

下面是我模拟winsock控件的两个类的代码,这两个类对TCPClient类和TCPlistener 类做了一些封装:

Imports System

Imports System.IO

Imports System.Net

Imports System.Net.Sockets

Imports System.Text

Imports Microsoft.VisualBasic

Public Class MyWinSockClient

 

 

    'Inherits System.Net.Sockets.TcpClient

    Public TcpClnt As System.Net.Sockets.TcpClient

    Dim WithEvents Tmr100ms As New Timer()

 

    Public Event DataArrival(ByRef Sender As MyWinSockClient, ByVal BytesTotal As Long, ByVal Data() As Byte)

    Dim InBuff(511) As Byte

    Dim Rl As Long '接收到的字节数

 

 

    Public ReadOnly Property Ifconnected() As Boolean

        Get

            Dim s As Socket = TcpClnt.Client

            If s.Connected = True Then

                Ifconnected = True

            Else

                Ifconnected = False

 

            End If

        End Get

    End Property

 

    Public Sub SendData(ByVal Data() As Byte)

        TcpClnt.GetStream.Write(Data, 0, Data.GetLength(0))

    End Sub

 

    Public Sub New()

        Tmr100ms.Interval = 100

        Tmr100ms.Enabled = True

        TcpClnt = New System.Net.Sockets.TcpClient

    End Sub

 

    Private Sub Tmr100ms_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr100ms.Tick

        If Me.Ifconnected = True Then

            If TcpClnt.GetStream.DataAvailable Then

                Dim i As Long

                Rl = TcpClnt.GetStream.Read(InBuff, 0, InBuff.Length)

                Dim B(Rl - 1) As Byte

                For i = 0 To Rl - 1

                    B(i) = InBuff(i)

 

                Next

 

                RaiseEvent DataArrival(Me, Rl, B)

 

            End If

        End If

    End Sub

 

  

End Class 'MyTcpClientDerivedClass

 

Public Class MyWinSockListener

 

 

    Inherits System.Net.Sockets.TcpListener

    Dim WithEvents Tmr100ms As New Timer()

 

    'Public Event DataArrival(ByVal BytesTotal As Long, ByVal Data() As Byte)

    Public Event ConnectionRequest(ByRef TcpClnt As System.Net.Sockets.TcpClient)

    Dim InBuff(511) As Byte调节这个缓冲区可以调节通讯数据的吞叶量

    Dim Rl As Long '接收到的字节数

 

    'Sub testmy()

 

    'End Sub

    Public ReadOnly Property Ifconnected() As Boolean

        Get

            Dim s As Socket = MyBase.Server

            If s.Connected = True Then

                Ifconnected = True

            Else

                Ifconnected = False

 

            End If

        End Get

    End Property

 

  

 

    Public Sub New(ByVal Ipaddr As IPAddress, ByVal Prt As Integer)

        MyBase.New(Ipaddr, Prt)

        Tmr100ms.Interval = 100

        Tmr100ms.Enabled = True

    End Sub

 

    Private Sub Tmr100ms_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr100ms.Tick

        If Me.Pending Then

            Dim client As System.Net.Sockets.TcpClient

 

            client = Me.AcceptTcpClient

 

            RaiseEvent ConnectionRequest(client)

 

        End If

    End Sub

End Class 'MyTcpClientDerivedClass

然后在原来放winsock控件的窗体中再声明这两个类的实例,下面这个窗体的类的代码:

Option Strict Off

Option Explicit On

Imports System

Imports System.IO

Imports System.Net

Imports System.Net.Sockets

Imports System.Text

Imports Microsoft.VisualBasic

Friend Class MBTCPsocket

    Inherits System.Windows.Forms.Form

    Public Tcpport As Integer

    Public ConnCol As System.Collections.Generic.List(Of MyWinSockClient)

    Dim IntMax As Integer

    Dim WithEvents TcpClnt As MyWinSockClient

    Friend WithEvents txtmbrv As System.Windows.Forms.TextBox

    Friend WithEvents txtmbsend As System.Windows.Forms.TextBox

    Friend WithEvents Button1 As System.Windows.Forms.Button

    Friend WithEvents CmdHide As System.Windows.Forms.Button

 

    Public WithEvents TcpSvr As MyWinSockListener

    Private Sub cmdhide_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdhide.Click

        Me.Hide()

    End Sub

 

    Private Sub Command3_Click()

        frmModbusserver.Show()

    End Sub

 

 

    'UPGRADE_WARNING: Form event Tcpsocket.Activate has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6BA9B8D2-2A32-4B6E-8D36-44949974A5B4"'

    Private Sub Tcpsocket_Activated(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Activated

        'Me.Visible = False

    End Sub

 

    Private Sub Tcpsocket_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load

      

    End Sub

 

    Private Sub Tcpsocket_FormClosing(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

        Dim Cancel As Boolean = eventArgs.Cancel

        Dim UnloadMode As System.Windows.Forms.CloseReason = eventArgs.CloseReason

        Me.Hide()

        Cancel = True

        eventArgs.Cancel = Cancel

    End Sub

    Private Sub TcpSvr_ConnectionRequest(ByRef TcpClnt As System.Net.Sockets.TcpClient) Handles TcpSvr.ConnectionRequest

 

        Dim Clnt As New MyWinSockClient

        'Dim Cnt As System.Net.Sockets.TcpClient

 

        Clnt.TcpClnt = TcpClnt

        AddHandler Clnt.DataArrival, AddressOf Me.TcpClnt_DataArrival

        ConnCol.Add(Clnt)

 

    End Sub

    Private Sub InitializeComponent()

        Me.txtmbrv = New System.Windows.Forms.TextBox

        Me.txtmbsend = New System.Windows.Forms.TextBox

        Me.Button1 = New System.Windows.Forms.Button

        Me.CmdHide = New System.Windows.Forms.Button

        Me.SuspendLayout()

        '

        'txtmbrv

        '

        Me.txtmbrv.Location = New System.Drawing.Point(12, 32)

        Me.txtmbrv.Multiline = True

        Me.txtmbrv.Name = "txtmbrv"

        Me.txtmbrv.Size = New System.Drawing.Size(502, 97)

        Me.txtmbrv.TabIndex = 0

        '

        'txtmbsend

        '

        Me.txtmbsend.Location = New System.Drawing.Point(15, 156)

        Me.txtmbsend.Multiline = True

        Me.txtmbsend.Name = "txtmbsend"

        Me.txtmbsend.Size = New System.Drawing.Size(498, 120)

        Me.txtmbsend.TabIndex = 1

        '

        'Button1

        '

        Me.Button1.Location = New System.Drawing.Point(87, 296)

        Me.Button1.Name = "Button1"

        Me.Button1.Size = New System.Drawing.Size(109, 33)

        Me.Button1.TabIndex = 2

        Me.Button1.Text = "Button1"

        Me.Button1.UseVisualStyleBackColor = True

        '

        'CmdHide

        '

        Me.CmdHide.Location = New System.Drawing.Point(264, 296)

        Me.CmdHide.Name = "CmdHide"

        Me.CmdHide.Size = New System.Drawing.Size(125, 32)

        Me.CmdHide.TabIndex = 3

        Me.CmdHide.Text = "隐藏"

        Me.CmdHide.UseVisualStyleBackColor = True

        '

        'MBTCPsocket

        '

        Me.ClientSize = New System.Drawing.Size(546, 376)

        Me.Controls.Add(Me.CmdHide)

        Me.Controls.Add(Me.Button1)

        Me.Controls.Add(Me.txtmbsend)

        Me.Controls.Add(Me.txtmbrv)

        Me.Name = "MBTCPsocket"

        Me.ResumeLayout(False)

        Me.PerformLayout()

 

    End Sub

 

    Private Sub TcpClnt_DataArrival(ByRef Sender As MyWinSockClient, ByVal BytesTotal As Long, ByVal Data() As Byte) Handles TcpClnt.DataArrival

        Dim B As Byte

        Dim j As Long

        Dim mbdata() As Byte

        Dim MBResponsedataFrame() As Byte

        Try

            mbdata = Data

            '显示

            If Me.Visible = True Then

                txtmbrv.Text = System.Text.Encoding.ASCII.GetString(mbdata)

            End If

            Mbs.InformClientDataArrival(HextoStr(mbdata, BytesTotal, 0))

            '获得反应帧

 

            MBResponsedataFrame = Mbs.GetResponseFrame(mbdata) '获取本地反应数据帧

 

            '-----------------------

            '显示

            If Not Me.Visible = False Then

                txtmbsend.Text = HextoStr(MBResponsedataFrame, MBResponsedataFrame.GetLength(0), 0)

            End If

            Mbs.InformClientDataResponse(HextoStr(MBResponsedataFrame, MBResponsedataFrame.GetLength(0), 0))

 

            '发送

            Sender.SendData(MBResponsedataFrame)

        Catch

 

 

        End Try

    End Sub

 

    Public Sub New()

      

    End Sub

    Public Sub New(ByVal TcpPort As Integer)

        TcpClnt = New MyWinSockClient

        Me.Tcpport = TcpPort

        TcpSvr = New MyWinSockListener(IPAddress.Parse("127.0.0.1"), TcpPort)

        ConnCol = New System.Collections.Generic.List(Of MyWinSockClient)

 

        TcpSvr.Start()

    End Sub

End Class

十三、关于调试和打包。VB 2008 VB开发环境设定默认在代码环境中运行就是Debug调试的。每次调试运行都会在obj目录下生成一个exe文件,且将其复制到Bin目录下,这个exe文件是含有调试信息的,尺寸也稍大。如果要发布程序则要点Build下的Build solution,即将其编译为最终发布程序,这时Bin下的exe程序就变为最终发布程序,可以打包了。

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值