您的位置:首页 > 编程语言 > VB

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

2010-06-03 16:48 507 查看
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程序就变为最终发布程序,可以打包了。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/SHIPENG_GAO/archive/2009/04/02/4043659.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: