我以前都是用C#来写,这次搞这个VB.NET项目,有点突然。还好语言都是相通的。
1.虽说以前的Microsoft Visual Basic和.NET都是微软自己的东西,可有很多功能的实现方式还不一样,特别是那些控件。
2.每个程序都会有自己的业务逻辑,有些可能会很复杂,甚至读别人的代码时你可能对业务逻辑那部分会完全一头雾水。
开始也打算在.NET环境下重做,可在做了一些尝试后发现根本没法了解那个VB6.0程序的业务逻辑,以致于从VB6.0转换到.NET下后,那些老的graph控件没法工作。和项目经理做了很多研究后,还是决定先让Microsoft Visual Studio替我们先把VB6.0项目转换生成一个VB.NET项目,然后在这基础上改。事实证明,这种做法很明智,因为相比在.NET环境下重做会少写很多代码,而且你几乎不用去管那个项目的业务逻辑。废话少说,下面介绍升级过程。
1.在机子上安装Microsoft Visual Basic,我用的是Microsoft Visual Basic 6.0中文企业版。作用有两个:(1)确保以前的VB项目能正常工作.(2)方便以后能回到这个老项目中进行一些调试。
2.打开你的Microsoft Visual Studio,接着执行File-Open-Project/Solution,在弹出的对话框找到将被转换的.vbp工程文件,选中并打开它。此时会弹出Visual Basic Upgrade Wizard。在这个过程你需要指定被转换过来的项目的位置以及项目类型。因为我这个是桌面程序,所以我选择了.exe类型。参数准备完后,IDE会需要比较长的时间来完成升级过程。
3.转换完成后,你会发现IDE提示了很多代码的错误。其实很多VB6.0里面的老控件都已经被Visual Studio转换过来了,或者Visual Studio里已经以其它相似的名字内置了对VB6.0老控件的支持。
有一点VB6.0里的DBGrid控件会被转化成.NET下vb.net教程的AxMSDBGrid.AxDBGrid类型的控件,这种控件在VB6.0里需要Data控件作为数据源。.NET已完全抛弃了Data控件,不再提供对它的直接支持,而选用了性能更高的ADO.NET组件。开始我们本打算原封不动的用转换过来的控件,后来发现这个AXDBGrid控件的DataSource属性必须要是一个ICursor,而当今现存的数据源控件除了Data控件都无法提供这个ICursor接口属性,但这个Data控件在.NET中是无法使用的。
最后不得已选用了.NET下标准的数据显示控件DataGridView,并用以下代码模拟出Data控件。
1 Public Solar As DAO.Recordset
2 ModelData = DAODBEngine_definst.Workspaces(0).OpenDatabase(Application.StartupPath + "\Cmpnents.mdb", False, False, "MS Access;PWD=" & pssss)
3 Solar = ModelData.OpenRecordset("SELECT * From SMake", DAO.RecordsetTypeEnum.dbOpenDynaset)
对上面的代码我得说明下:
1.DAODBEngine_definst是.VB文件中一个Module里声明的对象。代码如下:
Module UpgradeSupport
Friend DAODBEngine_definst As New DAO.DBEngine
End Module
2.其中DAO命名空间在dao360.dll中(你需要用regsvr32.exe注册该DLL,然后把它以COM组件的形式引入到自己的项目中),而VB中只能使用DAO350.DLL。
3.这里选用DAO.Recordset而不选用其它数据源是因为该对象本身提供了几乎Data控件所具有的所有方法,像MoveFirst(),MoveLast(),MoveNext()等方法,这样就可以减少对升级后的代码修改。
4.Recordset对象是无法直接作为DataGridView的数据源的,必须先把转化为DataTable对象,再把它作为DGV的数据源,转换代码如下:
1 Function RecordsetToDataTable(ByVal adoRS As DAO.Recordset, ByVal strTable As String) As DataTable
2
3 adoRS.MoveFirst()
4 Dim dt As DataTable
5 dt = New DataTable(strTable)
6 Dim i As Integer
7 Dim strcolname As String
8 Dim t As Type
9 Dim dr As DataRow
10
11 For i = 0 To adoRS.Fields.Count - 1
12 strcolname = adoRS.Fields(i).Name
13 t = adoRS.Fields(i).Value.GetType()
14 dt.Columns.Add(strcolname, t)
15 Next
16 While (Not adoRS.EOF)
17 dr = dt.NewRow()
18 For i = 0 To adoRS.Fields.Count - 1
19 dr(i) = adoRS.Fields(i).Value
20 Next
21 dt.Rows.Add(dr)
22 adoRS.MoveNext()
23 End While
24
25 Return dt
26
除了这个麻烦的Data控件,对VB6.0里的Printer对象我也得说说。这个Printer对象提供了很多.NET里的PrintDocument组件无法直接实现的功能,像对窗口,图片的缩放打印。于是我期盼着能直接使用这个Printer对象。查了下MSDN,它告诉我:这个对象在.NET也有内置的支持,于是我按照它说的安装了VisualBasicPowerPacksRedist.msi并引入相关的DLL组件(相关的说明及操作,请参考MSDN:Printer Class (Microsoft.VisualBasic.PowerPacks.Printing.Compatibility.VB6) | Microsoft Docs),并引入了 Microsoft.VisualBasic.PowerPacks.Printing.Compatibility.VB6命名空间,这时与VB6.0中Printer对象有关的方法可以用了,可在执行打印时完全没任何纸从打印机出来,如此weird,呵呵,除了这个词我实在不知道还有哪种语言哪个形容词能描述它。最后我不得不用PrintDocument组件实现它。对于这个问题,欢迎大家和我交流。
对于其它的VB组件转换后,大部分都能在.NET里,只要确保添加了对相应组件的引用即可。
另外,你如果想知道VB6.0的控件在VB.NET是否有相应的支持,请参考:Developer tools, technical documentation and coding examples | Microsoft Docs
写到这里感觉自己有点啰嗦了. 当然,这个转换过程涉及到许多细节要处理,这里我不可能面面俱到。如有问题,欢迎和我交流。