The VFPXporter tool is created to ease the move of your Visual FoxPro (VFP) Application in .NET, using a language you already know, with help of XSharp.
1. Minimum changes to your code during export.
2. Keep the original code as comment if any change is made.
3. Move VFP Forms to Windows Forms, using an adaptation layer/library called XSharp.VFP.UI.Dll.
4. Move VCX libraries as external projects containing Forms/Controls.
5. Create real Windows Forms solution/project so you can use any existing third party for .NET in your application.
First, open the Settings dialog box:
•Default VFP item Folder: The folder where VFPXPorter will start to search for elements to export per default.
•Default Output Folder: The folder where the VFPXPorter will create the generated export content.
•Default exporter resources Folder: The folder where the VFPXPorter will look for extra templates, Libraries, Tools, etc.
You can then:
•Reset Settings to their default values.
•Open Settings Folder where the .json settings file is stored (e.g., for backup).
Check or Uncheck the export settings. Usually, the default values are the best choice.
•Default Fields modifiers: When exporting a CLASS, set the default Field visibility.
•Ignore export Errors: Allows to continue the export process in case of errors. All errors are logged in the destination folder.
•If needed, you can specify your own name for the Folders where elements are exported.
•Each ClassLibrary is in a SubFolder: If your application is using libraries, it is a good practice to export them separately.
•Empty the destination folder: Each time you export an element, the destination folder is emptied
•Input Project: Search for the .PJX file to export.
•Output Folder: Indicate where the VFPXPorter will write the generated files.
•Analyze: Allow to look at the content that the VFPXPorter has detected in the Project.
•Export: Export the project
•Open: Open the folder where the files where written.
The generated folder should contain several folders (One per Library if you have checked the setting, One for detected FreeTables, One for XSharp Tools, etc.).
You will find a file with the same name as the exported project with .SLN as extension. This is the MS Visual Studio solution file that will group all exported top-level items (Project, Libraries, etc.).
This is the file you should open first.
The VFPXPorter will read your project and its elements. It will identify their type and generate some X# code.
In order to generate that code, it will look into the Data folder.
There, we will find several .JSON files that are used as conversion Rules.
The documentation for these rules is available in VFPXPorter repository on GitHub.
Then, to generate the files, it will use some templates; one per type of file. You can find these templates on GitHub: Templates.
Please find here a list of the common troubles we will face when converting your VFP GUI code to X# and WinForms.
When converting your Application from VFP to X# and WinForms, it's important to remember that these two "worlds" use a different point of view to your Form.
In VFP, events are routed to the Controls.
For example, each button on the Form has its own class that INHERITs from the base-class CommandButton, and is an instance of that particular class. This structure allows you to override Events and Methods at that level, providing extensive control over what's happening there.
In WinForms, events are routed to the Owner of the Controls: The Form
Therefore, the convention is to prefix the EventHandlers and Methods with the name of the Control.
For instance, if button1 raises a click event, the name of the handler is button1_click.
Similarly, if a Form is raising an event, since the Form itself is the class, the name will be nameOfTheForm_Event.
This behavior can be changed through an exporter setting:
•Prefix Event methods with FORM name
The generated code contains a Start() Function, which is the Startup Object of the generated application. If you are also using a Start() Function in your VFP Code, you will have to rename it after export.
With VFP, the Init() method is called when an object is created.
With X#, calling the Constructor() of a class (with the MyClass{} syntax), won't automatically called the Init() Method.
This process is emulated by the InitType.prg template that is used during export.
With Controls, the Init() Method is called when the Handle is created. This code is generated by the InitType.prg template used during export.
Unfortunately, these cannot be handled automatically, as that would break the Windows Forms designer in Visual Studio.
Setting a BackColor or ForeColor with an RGB, like :
this.Label1.ForeColor = RGB(255,0,0)
Should be converted to :
this.Label1.ForeColor = System.Drawing.Color.FromARGB( 255,0,0) )
BUT.... If you had a function called RGB() that returns a System.Drawing.Color in a PRG file, in the Tools folder of the Exporter, it will be part of your Exported Solution, and it will supersede the XSharp Runtime definition, which will do the trick!
In X#, a Property holds a Value that is set/get with the equal sign, while a Method contains code that is executed when called : And you can make the difference, because Method call ends with parenthesis.
While this is allowed in VFP, you will have to correct that in X#:
this.Refresh
Should be corrected as
this.Refresh()
These can be corrected at export time, if you check the "Convert Statement to Call" in settings.
The handled statements are in the Statements.json file.
To modify a Form with the Windows Form Designer in Visual Studio, the Properties must respect the WinForm casing. Therefore, you may need to add some properties to the PropRules.json in order to automatically convert them.
That's why ShowInTaskBar appears in the rules as ShowInTaskbar. (Note the lowercase "b").
The Parent Property is already defined in Windows Forms, and is strongly typed to a System.Windows.Forms.Control object. To avoid problems, and ease the port of applications, the support library contains a property called _Parent that accesses the Control's parent, but as a weakly typed Object.
This will force X# to a late-bound call, and could help in resolving access to ported code.
The call to _Parent is automatically generated by the XPorter.
In object with Parent, you may sometimes directly call Event handlers in your VFP code.
This might be problematic, and for example, a direct call to the Click event of a button will fail.
This.Parent.cmd_prec.Click
During export, the This will be turned to ThisObject, the parent.
In X#, array elements are accessed using brackets [].
In VFP, however, it is possible to use parenthesis ().
This can create issues when accessing a .Net typed-array.
To simplify the porting of VFP-applications, some array access operations have been converted to method calls in the XSharp.VFP.UI, the Control layer that eases access to .NET Controls using VFP syntax.
x = __screen.FormCount
__screen.Forms(x-1).Release() // Here, Forms array will be replaced by Forms Method call.
In VFP, it is possible to reference the current WorkArea/Cursor using its name, and to point to specific fields by specifying their name after a Dot selector, like with :
? movie.title
Unfortunately, in X# the Dot selector is used for Objects, so you will have to use an arrow as selector, like with:
? movie->title
You can use an undeclared var anywhere in your code. This is something that X# will recognize and support.
In such case, X# will silently create a MemVar: a local, untyped, var.
But there are some cases, where this will not work. For example:
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
In the previous code, the var laErr has never been declared at this level, but it is used as a REF var by the AError() function.
This type of construction is not supported by X#. You will have to create a local variable laErr first.
When building your VFP App, you may call some functions that are not (yet) supported by X#.
The compiler will express a warning (XS0618), but will generate an Exe, that will certainly crash at Runtime.
To avoid that, indicate these warnings as Errors.
To do so, with MS Visual Studio, follow these steps:
•Open the Properties of the Project;
•Go To Build;
•In section Treat Warning as Errors, enter the Specific Warning : XS0618.
VFP GUI Control library is very different from .NET Windows Forms: Properties, Methods and Event Handling are very different.
In order to offer GUI export, VFPXPorter is using an adaptation layer, XSharp.VFP.GUI
That library contains some controls that micmics the way VFP is behaving. It exposes the originals properties of VFP and converts them to their .NET Windows Forms counterparts.
Some controls might be missing, as well as some Properties/Methods/Event. Please report your troubles in the XSharp Forums.