robert wrote:We have been studying how we can implement our tool to convert FoxPro forms code to .Net using Windows Forms.
From what we have seen, FoxPro allows you to write Events (Event Handlers) at the control level.
For example if a form has 2 button controls, then each of these buttons can have a Click event
with the code that gets executed when that button is pressed. This click event belongs to the button.
The form on which the buttons are located can also have a click event.
Yes, the form will "house" any event code written for controls aggregated on the form. But IIRC that is not a special feature of the form, but of ANY container which has a child control aggreagated, as an "object instance" is aggregated, not a class where properties and methods can be overwritten at the class level. This will result in method names duplicating the object name path from the outermost container.
In Windows Forms there are also click events at the form level and the control level, so that looks very much like FoxPro. (On the other hand, Windows Forms controls typically include many dozens of properties and events (for example
Windows Forms Events ), which is not like FoxPro's compact list).
However, in a normal Windows Forms window, when designed with the Windows Forms editor, the events/ event handles for the form and the events for the controls all become event handlers (methods) at the form level.
We can migrate your VFP form code to Windows Forms fairly easy and we can also migrate the events.
To migrate same named events for different controls and maybe also a same named event at the form we would have to give each of them a unique name. So when your form has OkButton and CancelButton the events would be called something like PROCEDURE OkButton_Click and PROCEDURE CancelButton_Click and PROCDURE Form_Click.
OkButton can be added to a form many times, as long as it is always surrounded by another container - inside each container the names must be unique, NOT for total form.
Code: Select all
MyForm.Pgf1.PageEntry.OkButton
MyForm.Pgf1.PageMiddle.Container.OkButton
MyForm.Pgf1.PageLast.ContainerBottom.CmdGroup.OkButton
MyForm.Pgf2.PageMain.CmdGroup.OkButton
is valid vfp structure having all that IN THE SAME FORM - which would not be ok for WinFroms IIRC. I think a naming convention like "MyForm#Pgf1#PageLast#ContainerBottom#CmdGroup#OkButton#click()" for vfp# might be safest, as it sidesteps the already overused dot (object path, namespaces) in Dotnet.
And we would be able to migrate the existing code out of the form into these methods.
For methods that receive parameters we would also be able to send the same parameters to these methods.
So far no problems, however there is one big difference:
Inside VFP in the Click Event for OkButton the variable "this" refers to the control and "thisform" to the form.
When the same code is in an event on the form then "this" is the form and not the control.
If you are using "this" a lot in the button event handlers, then that could be a problem, because you (or we) would have to make a lot of changes.
We could automate that in the conversion and make a local variable "thiscontrol" which points to the control and rename all references from the original code to "this" to "thiscontrol" and then rename all references to "thisform" to "this.
But we are not sure if that would result in a situation that would make everybody happy.
Count me among those unhappy with such a solution.
CAVEAT EMPTOR: the following is only my mental model, NOT verified debugging vfp runtime at C-level
Some OOP languages have explicit pointers to current/housing object (think Python self as first method parameter or the JS gymnastics with apply, bind and call), others just hide the self reference. I envisioned vfp method call to always follow the pattern of
Code: Select all
procedure MyMethod(Hidden_Implicit ThisForm, Hidden_Implicit This, OtherParameters)
Of course a hidden property with an access method walking the way up container hierarchy to next containing form or set during addobject() would also work, but "Parent" is a property, "ThisForm" not.
"ThisControl" is palatable (portable code via preprocessor in vfp), "ThisForm" exchanged with "This" not.
Better to add a "__ThisForm" property to each control and mangle "ThisForm" on the vfp# side via preprocessor into a call to "ThisControl.__ThisForm" for those methods defined at the control class level.
There is another solution to that
When we detect that you have created an event handler for a control then we can create a subclass of the Button class for the OKButton and another subclass of the Button class for the CancelButton.
The Click event for each button would then be added to the subclass for that button. Conceptually that is not a problem and the code would remain very much like it is in VFP.
I cannot visualize that idea totally - but include complex controls added in already multiple times overwritten event delegate each called via dodefault() early in your testing. Gut twitches here that you might have to add a stack of events as a single object might be in trouble or not be enough.
It has been too long since reading about the option to (re)name variables to keywords with leading @ - back when I first read about it, I tought it was probably used to switch IL "this" to IronPython "self", but never looked hard. Perhaps that way the "This" of Winform event could be mapped into "Thisform" and the "ThisControl" into "This" in the event method ?
[snipped part of custom editor]
I dislike the idea of a custom editor - alternative POV in 3. post...
We really would like your input on this. To simplify the above to 3 questions:
1) Are you using "this" a lot in your event handlers ?
Yes
2a) Would it be a problem for you if we change "this" to "thiscontrol" for event handlers
No
2B) Would it be a problem for you if ( then "this" becomes the same as "thisform")
YES
3) If this is a problem, do you think it would be a good idea to have a special form editor and automatically generate subclasses to solve this problem ?
No, I think creating a special Winform editor is not the best solution - next post, but have to order thoughts first...
regards
thomas