VFPXporter 工具旨在通过 XSharp 帮助您将 Visual FoxPro (VFP) 应用程序迁移到 .NET,使用您已经熟悉的语言。
1.在导出过程中对代码的更改最小化
2.如果进行了任何更改,将原始代码保留为注释
3. 使用名为 XSharp.VFP.UI.Dll 的适配层/库,将 VFP 表单迁移到 Windows Forms
4. 将 VCX 库作为包含表单/控件的外部项目进行迁移
5. 创建真实的 Windows Forms 解决方案/项目,以便您可以在应用程序中使用任何现有的第三方 .NET 库
首先,打开设置对话框:
•默认 VFP 项目文件夹(Default VFP item Folder):VFPXPorter 将默认从该文件夹开始搜索要导出的元素。
•默认输出文件夹(Default Output Folder):VFPXPorter 将在该文件夹中创建生成的导出内容。
•默认导出资源文件夹(Default exporter resources Folder):VFPXPorter 将在该文件夹中查找额外的模板/库/工具等。
然后你可以:
•重置设置为默认值(Reset Settings)。
•打开存储 .json 设置文件的设置文件夹(Open Settings Folder), 例如用于备份。
检查或取消检查导出设置:通常默认值是最佳选择。
•默认字段修饰符(Default Fields modifiers):导出类时,设置默认字段的可见性。
•忽略导出错误( Ignore export Errors):允许在出现错误时继续导出过程。所有错误都会记录在目标文件夹中。
•如果需要,您可以为导出元素的文件夹指定自己的名称。
•每个类库在一个子文件夹中(Each ClassLibrary is in a SubFolder):如果您的应用程序使用库,最好将它们单独导出。
•清空目标文件夹(Empty the destination folder):每次导出元素时,目标文件夹都会被清空。
•输入项目(Input Project):搜索要导出的 .PJX 文件。
•输出文件夹(Output Folder):指定 VFPXPorter 将生成文件写入的位置。
•分析(Analyze):允许查看 VFPXPorter 在项目中检测到的内容。
•导出(Export):导出项目。
•打开(Open):打开包含生成文件的文件夹。
生成的文件夹应包含多个文件夹(如果已勾选设置,则每个库一个文件夹,一个用于检测到的 FreeTables,一个用于 XSharp 工具,...)。
您将找到一个与导出项目同名的文件,扩展名为 .SLN。这是 MS Visual Studio 解决方案文件,将组合所有导出的顶级项目(项目、库等)。
这是您应首先打开的文件。
VFPXPorter 将读取您的项目及其元素。它会识别它们的类型并生成一些 X# 代码。
为了生成代码,它会查看 Data 文件夹。
在那里,我们可以找到几个 .JSON 文件,它们被用作转换规则:
这些规则的文档可在 GitHub 的 VFPXPorter repository 中找到
然后,它将使用一些模板来生成文件: 每种文件类型一个。您可以在 GitHub 上找到这些模板 : 模板
在将您的 VFP 图形用户界面代码转换为 X# 和 WinForms 时,我们会遇到一些常见问题,请参见以下列表。
将应用程序从 VFP 转换到 X# 和 WinForms 时,您必须牢记这两个 “世界” 对您的窗体使用不同的视角。
在 VFP 中,事件被路由到控件。
因此,我们可以认为,例如,窗体上的每个按钮都有自己的类,该类继承自基类 CommandButton,并且是该特定类的实例: 因此,您可以重写该级别的事件和方法,这样就可以对发生的事情进行大量控制。
在 WinForms 中,事件会传递给控件的所有者: 表单
因此,使用方法是在事件处理程序和方法的前缀加上控件的名称。
如果 button1 引发了单击事件,那么处理程序的名称就是 button1_click。
如果是表单引发事件,由于表单是类,因此处理程序的名称将是 nameOfTheForm_Event。
您可以通过导出器设置更改该名称:
•(以 FORM 名称作为事件方法的前缀Prefix Event methods with FORM name)
生成的代码包含一个 Start() 函数,它是生成应用程序的启动对象。如果您在 VFP 代码中也使用了 Start() 函数,则必须在导出后对其进行重命名。
在 VFP 中,创建对象时会调用 Init() 方法。
在 X# 中,调用类的 Constructor() (使用 MyClass{} 语法)不会自动调用 Init() 方法。
在导出过程中,InitType.prg 模板会模拟这一过程。
对于控件,在创建句柄时会调用 Init() 方法。这段代码由导出时使用的 InitType.prg 模板生成。
遗憾的是,这些都无法自动处理,因为这会破坏 Visual Studio 中的 Windows 窗体设计器。
使用 RGB 设置 BackColor 或 ForeColor,如 :
this.Label1.ForeColor = RGB(255,0,0)
将被转换为:
this.Label1.ForeColor = System.Drawing.Color.FromARGB( 255,0,0) )
BUT.... 如果您在 PRG 文件中使用名为 RGB() 的函数返回 System.Drawing.Color 颜色,那么它将成为您导出解决方案的一部分,并取代 XSharp Runtime 定义,这样就可以解决这个问题了!
在 X# 中,“属性” 包含一个用等号设置/获取的 “值”,而 “方法” 包含调用时执行的代码。
这在 VFP 中是允许的,但在 X# 中您必须纠正这一点
this.Refresh
应更正为:
this.Refresh()
如果在设置中勾选 “将语句转换为调用(Convert Statement to Call)”,就可以在导出时纠正这些问题。
处理过的语句在 Statements.json 文件中。
要使用 Visual Studio 中的 Windows 窗体设计器修改窗体,属性必须遵守 WinForm 的格式。因此,您可能需要在 PropRules.json 中添加一些属性,以便自动转换它们。
这就是 ShowInTaskBar 在规则中显示为 ShowInTaskbar 的原因(注意小写的 b)。
Windows 窗体中已经定义了父属性,并将其强类型化为 System.Windows.Forms.Control 对象。为了避免麻烦并简化应用程序的移植,支持库中包含了一个名为 _Parent 的属性,它可以访问控件的父对象,但却是一个弱类型对象。
这将迫使 X# 进行后期绑定调用,并有助于解决移植代码的访问问题。
对 _Parent 的调用由 XPorter 自动生成。
在父对象中,您有时可能会在 VFP 代码中直接调用事件处理程序。
这可能会有问题,例如直接调用按钮的 Click 事件就会失败。
This.Parent.cmd_prec.Click
导出时,“This” 将转为父对象 ThisObject。
在 X# 中,使用括号 [] 访问数组元素。
在 VFP 中,您可以使用括号 () 。
但在访问 .Net 类型数组时,这可能会造成问题。
因此,为了简化 VFP 应用程序的移植,在 XSharp.VFP.UI 控制层中,一些数组访问被转为方法调用,从而简化了使用 VFP 语法访问 .NET 控件的过程。
x = __screen.FormCount
__screen.Forms(x-1).Release() // 在这里,表单数组将被表单方法调用所取代。
在 VFP 中,可以使用当前工作区/Cursor 的名称来引用当前工作区/光标,也可以通过在 Dot(.) 后指定字段名称来指向特定字段,例如使用 .VFP:
? movie.title
遗憾的是,在 X# 中,Dot(.) 用于对象,因此您必须使用箭头作为选择器,如
? movie->title
您可以在代码的任何地方使用未声明的变量。X# 会识别并支持这一点。
在这种情况下,X# 会默默地创建一个变量:一个未类型化的局部变量。
但在某些情况下,这样做是行不通的。例如
IF SQLExec(nHandle,"SELECT * FROM employees ORDER BY id ASC LIMIT 1","CurResult") <=0 THEN &&& validate error first.
Aerror(laErr)
Messagebox("Check the following error: " + Chr(13) + laErr[2],'Alert',3000)
RETURN .F.
ENDIF
在代码中,变量 laErr 从未在这一级声明,但它被 AError() 函数用作以引用方式传递的参数。
X# 不支持这种结构。您必须先创建一个局部变量 laErr。
在创建 VFP 应用程序时,您可能会调用一些 X# 尚不支持的函数。
编译器会发出警告 (XS0618),但生成的 Exe 肯定会在运行时崩溃。
为了避免这种情况,可以将这些警告显示为错误。
为此,请按照以下步骤使用 MS Visual Studio:
•打开项目属性
•转到 “生成”(Build)
•在 “将警告视为错误(Treat Warning as Errors)”部分,输入特定警告(Specific warnings:):XS0618
VFP GUI 控件库与 .NET Windows Forms.UI.Dll 有很大不同: 属性、方法和事件处理都非常不同。
为了提供图形用户界面导出,VFPXPorter 使用了一个适配层:XSharp.VFP.GUI。
该库包含一些与 VFP 行为方式类似的控件。它公开了 VFP 的原始属性,并将其转换为 .NET Windows Forms 对应的属性。
某些控件可能会丢失,某些属性/方法/事件也是如此: 请在 XSharp 论坛上报告您的问题。