We need your input on how to migrate FoxPro forms

This forum is meant for questions about the Visual FoxPro Language support in X#.

User avatar
Chris
Posts: 4928
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

We need your input on how to migrate FoxPro forms

Post by Chris »

Guys, there is absolutely no problem at all using "This" in "regular" code. The only place where it complicates things supporting "This" as a reference to the control in question is in event code, and specifically in automatically generated event code by the visual form editor.

The reason is that the standard Windows Forms form editor generates Click, Mouse, keyboard etc events code as part of the containing form class, so naturally "This" refers to the form itself, not to the control that triggered the event to happen. We can workaround this in a few ways, some of which are:

1) Do not use "This" in event code, instead use a path to the control in question with "Thisfor.Control1.Control2..." instead
2) Use some compiler trickery and possibly some leading code inside the event methods to do the translating between WinForms and VFP style
3) Create a custom Form Designer for ported VFP apps, where we will have full control on what we generate, how and where

But that's only related to using "This" inside event handlers of the visual form designer, this discussion does not affect any other usage of "This" at all. So regarding:

atlopes wrote:Chris asked:
Another question is, since it is obvious from your replies, that using "this" is very common, would it be acceptable for you to start using only "thisform" from now on in event methods? So, for example the click event code of a command button control that looked like:

This.Caption = "I got clicked!"

would be typed in X# as

Thisform.Button1.Caption = "I got clicked!"
If I'm getting this right, this would break all of the VFP OOP building because we wouldn't be able to subclass a button to be used in a form or any other container.

Code: Select all

DEFINE CLASS SensitiveButton AS CommandButton

  PROCEDURE Click
     This.Caption = "Ouch! I got clicked!"
  ENDPROC

ENDDEF
this would still work perfectly fine, completely unmodified from the existing FoxPro version of the code.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
robert
Posts: 4533
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

We need your input on how to migrate FoxPro forms

Post by robert »

Maybe to clarify a bit more:

In the VFP form editor when you double click on a button you create a click event for a button. This code runs in the context of the button and when you use "This" inside this code it refers to the button. So it seems that VFP "magically" creates a subclass from the Commandbutton involved. Otherwise it could never use "This" to refer to the button. Or it uses another trick where it runs the code as an extension to the button and automatically adds a "This" variable to this code that points to the button.
We do not want to use "dirty" tricks like that, so to be able to refer to the button with "This" we would have to add a subclass.
This is exactly what we propose with the "Custom editor". The difference is that we no longer hide this subclassing from you but you would be able to see the subclass in your code.

The alternative would be to use the normal Windows.Forms editor and create the events on the form, but in that case "This" would point to the form. "This.CommandButton1" would point to the button.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
atlopes
Posts: 83
Joined: Sat Sep 07, 2019 11:43 am
Location: Portugal

We need your input on how to migrate FoxPro forms

Post by atlopes »

Chris,

At the risk of missing something obvious...

If you ask a VFP developer if he/she is comfortable with different meanings for "This" in the code he/she writes, I can't expect another answer than "No, I'm not." But I may not know the VFP community as well as I would imagine.
1) Do not use "This" in event code, instead use a path to the control in question with "Thisfor.Control1.Control2..." instead
To a VFP developer, this option would be the same as saying, "forget all the classes you use now." Event code is coupled to the class of objects, and we expect it to be defined regardless of its container hierarchy if needed.

For instance (this is just an illustration):

Code: Select all

DEFINE CLASS SaveButton AS CommandButton
  Caption = "Save"
  PROCEDURE Refresh
    This.Enabled = USED()
  ENDPROC
  PROCEDURE Click
    IF USED()
      TABLEUPDATE()
      MESSAGEBOX("Current record was saved")
    ELSE
      This.Refresh()
    ENDIF
  ENDPROC
ENDDEF
The VFP form editor lets you put this new class of objects anywhere in the form, directly over the form itself or in any of its sub-containers, with no need to rewrite the code for Refresh and Click in each instance.

Did I understood wrong, or are you saying that with WinForms, to which I'm not familiar at all, as I hope to be obvious, each of these "Save" buttons will require to have their event code rewritten?
2) Use some compiler trickery and possibly some leading code inside the event methods to do the translating between WinForms and VFP style
I can't comment on this approach failing to anticipate its pains and gains, but taking into account this thread, I would dare to say that the difference between WinForms and VFP is not of style but of concept.
3) Create a custom Form Designer for ported VFP apps, where we will have full control on what we generate, how and where
Yes! ;-)
atlopes
Posts: 83
Joined: Sat Sep 07, 2019 11:43 am
Location: Portugal

We need your input on how to migrate FoxPro forms

Post by atlopes »

Robert,
In the VFP form editor when you double click on a button you create a click event for a button.
Not exactly. The Click event is part of the CommandButton core class, as it is of all the UI related objects. The form editor does not create it.

The VFP form editor opens the code editor at the point you mentioned, in the code for the Click event, just as a matter of convenience. If one chooses to edit the code of other methods or events, such as Init or Move, the next double-click will open the code editor there, and not at the Click event code.
This code runs in the context of the button and when you use "This" inside this code it refers to the button. So it seems that VFP "magically" creates a subclass from the Commandbutton involved. Otherwise it could never use "This" to refer to the button. Or it uses another trick where it runs the code as an extension to the button and automatically adds a "This" variable to this code that points to the button.
We do not want to use "dirty" tricks like that, so to be able to refer to the button with "This" we would have to add a subclass.
This is exactly what we propose with the "Custom editor". The difference is that we no longer hide this subclassing from you but you would be able to see the subclass in your code.

The alternative would be to use the normal Windows.Forms editor and create the events on the form, but in that case "This" would point to the form. "This.CommandButton1" would point to the button.
More to the/your point: I don't think this problem pertains only to the WinForms editor. Instead, it involves all of the VFP class structures.

In VFP, a class instance, that is, an object may extend its class by changing the code and values of methods and properties.

This "magical" stuff, to use your words, is not limited to forms, and is consistently applied to all objects instantiated inside a container.

Code: Select all

LOCAL CA AS Class_A

m.CA = CREATEOBJECT("Class_A")
m.CA.Dependent_B.Method_XYZ()

DEFINE CLASS Class_A AS Custom

    ADD OBJECT Dependent_B AS Class_B

    PROCEDURE Dependent_B.Init  && the instance extends the class

        This.Value = "You"

    ENDPROC

ENDDEFINE

DEFINE CLASS Class_B AS Custom

    Value = "Me"

    PROCEDURE Method_XYZ

        ? This.Value

    ENDPROC

ENDDEFINE
Displays

Code: Select all

You
This is precisely what happens inside a form with its buttons' Click events.

I fully agree that a specialized form editor would be required to match VFP's form editor, but I think that the problem you're trying to sort out is not limited to forms.
pluisje
Posts: 4
Joined: Mon Jun 10, 2019 2:25 pm

We need your input on how to migrate FoxPro forms

Post by pluisje »

... but I think that the problem you're trying to sort out is not limited to forms.
Interesting thought.

In this thread we are constantly talking about a form editor. But now I realize that I have not used the VFP Form Designer for years. I only use the Class Designer because I create all kinds of objects that in the end come together as something that is recognizable to the user as a form or an application.
User avatar
Chris
Posts: 4928
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

We need your input on how to migrate FoxPro forms

Post by Chris »

Thank you very much guys again for your very helpful posts! Not quoting you, because it would become a huge post, but replying on your points:

- The concept that the code of the events becomes actually a part of the control (or container) class itself is something we did not think of, although we are familiar with that, because it is possible to use this also in VO. Bad news is that "as is" it cannot be implemented under .Net (in which it is not allowed to plunge in code to an object from the "outside"), but good news is that it can be implemented with subclassing as mentioned above, or maybe even with extension methods under some preconditions.

- Any kind of control or container or any other code that is not directly generated by the top level visual window designer would not need any change at all. Everything will work in X# exactly like it did also in VFP, with zero changes (regarding that matter at least). The only question is regarding the code generated by the form designer. In .Net WinForms, when you design a form with a button on it and a click event for the button, the pseudo code generated looks like:

Code: Select all

DEFINE CLASS MyAppWindow
  [CLASS MyAppWindow] MEMBER Button1 AS CommandButton
  [CLASS MyAppWindow] FUNCTION Initialize()
  ...
  [CLASS MyAppWindow] FUNCTION Button1_click
    This.Caption = "Main window caption"
    This.Button1.Caption = "Button caption"
END DEFINE CLASS
So as you can see, the click event handling code is generated as part of the container main window, not as a member of the Button/CommandButton class. This code is generated automatically by the VS visual editor and we do not have control on this design, this is why why cannot change the way it works.

Another issue with using the standard VS window editor, is that there is a difference in some of the property names between Windows Forms and VFP forms, for example Winforms uses the term "Text" for what "Caption" is referred to in VFP. That's not a big problem, we can define also a "Caption" property in a subclass of the WinForms window class, so FoxPro designers can continue using it, exactly like they were used to before (assuming you do not like the idea of using "Text" instead of "Caption" from now on!). Only issue is it may become a bit messy because the VS designer will be showing both "Caption" and "Text", both describing the same thing, while with a custom window editor, we can make it display only the properties available in VFP and we can also give to the Properties editing toolwindow the same visual looks and feel it has in VFP.

The main problems with creating a custom designer is that it is more work for us :) and that it will make it difficult to mix in the same designed window both VFP-style controls AND the myriads of 3rd party controls available for use in .Net. There's absolutely no problem including different forms designed both by our (possible) custom editor AND the standard VS editor in the same application though!
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
mainhatten
Posts: 200
Joined: Wed Oct 09, 2019 6:51 pm

We need your input on how to migrate FoxPro forms

Post by mainhatten »

Chris wrote: 1) Do not use "This" in event code, instead use a path to the control in question with "Thisfor.Control1.Control2..." instead
Chris,
even if only in form-coded events the path to the control had to be coded starting from thisform, this will make refactoring such event code into newly created subclass more error prone. Imagine that at form level in some valid events the colour of the control changes if .value is not valid. Later on that colour change is not wanted for the single control it was coded in, but for a number of controls and a subclass of the control currently aggregated is created and aggregated instead. In the newly created subclass you have to code from this again, which is exactly the code already existing in the version used by traditional vfp.

Refactoring is done seldom enough - do not make it harder ;-)

regards

thomas
mainhatten
Posts: 200
Joined: Wed Oct 09, 2019 6:51 pm

We need your input on how to migrate FoxPro forms

Post by mainhatten »

atlopes wrote:Robert,
In the VFP form editor when you double click on a button you create a click event for a button.
Not exactly. The Click event is part of the CommandButton core class, as it is of all the UI related objects. The form editor does not create it.
Antonio,
I think we can agree to say form editor creates a new event handler. The problem here is that - IIRC even according to vfp documentation - object instances are added to containers, and in vfp OOP the method code (which the event handlers are) cannot (read: as documented!) deviate from the class code, as functions/methods are not first order in vfp.
I believe that this is an area where vfps internal prototypal nature comes into play, esp. if you look at the vfp method signature

Code: Select all

    PROCEDURE Dependent_B.Init  && the instance extends the class
sporting the dots needed for the object path, but the procedure itself is defined at container class level, it can only map the way to the instance object via dots in method name.
If you consider how you would code that in prototypal Javascript

Code: Select all

JS_cnt.JS_OKbtn.click = clickhandler_writtenatcontainer
JS_cnt.JS_OKbtn.Prototype = WhaterverFitsBest

JS_Form.JS_cnt.JS_OKbtn.click = clickhandler_writtensomewhere
JS_Form.JS_cnt.JS_OKbtn.Prototype = JS_cnt.JS_OKbtn
most of the "magic" is explained. When you write:
In VFP, a class instance, that is, an object may extend its class by changing the code and values of methods and properties.
This describes the behaviour ONLY of the add/newobjected class via "containership method mapping" - normally methods are unchangeble. Roberts "context" description is very fitting.
Kudos to you for giving short examples in code to the things I only described in text...

regards
Thomas
mainhatten
Posts: 200
Joined: Wed Oct 09, 2019 6:51 pm

We need your input on how to migrate FoxPro forms

Post by mainhatten »

[Consider this not Post3, but 2B]
Robert, Chris and others on Dev Team:
I don't remember if I pointed out here that vfp, while aiming at classical inheritance and describing its inheritance in "classic ways", is actually implemented as prototypal inhertance. Christoph Wollenhaupt explains it in more detail somewhere on foxpert on the inner workings of vfp and recently over on Level Extreme there were a few threads on how to tweak code to sidestep running identical .Init() code for oodles of contorls
Thread ID:01672005; esp. Message ID:01672056, also Thread ID:01672305; esp. Message ID:01672390

That might explain some of the "magic" alluded to previously, see also my reply to Antonio.

Just to be certain: Read the hints as possible explanation - NOT as something to re-implement in vfp# dialect. The "trick" described at Level Extreme is "coding to/optimizing implementation", which should NOT be read as example for xSharp-vfp! If something surprises old foxxers like Dragan and Tore, it is definately not in common usage...

Going back to the original post:
a special form editor and automatically generate subclasses to solve this problem ?
I tentatively guess that generating subclasses for any containership-level (including subclassed complex controls, NOT form level!) would be a workable solution. But that should work on compiler level, not depend on any form editor.

regards
Thomas
User avatar
robert
Posts: 4533
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

We need your input on how to migrate FoxPro forms

Post by robert »

Antonio,
I don't think you completely understood what I tried to say:
If you look at the designed VFP form then the form itself represents a class. You can see that also if you generate the source version of this with FoxBin2Prg. The Data environment is also a class.

Code: Select all

DEFINE CLASS dataenvironment AS dataenvironment 
DEFINE CLASS form1 AS form 
Each control on the form is defined as an instance of one of the base classes or as a custom class

Code: Select all

    ADD OBJECT 'btnFirst' AS commandbutton
The events for the buttons are defined like this:

Code: Select all

PROCEDURE btnFirst.Click
		this.Caption = "I was clicked"
	ENDPROC
This procedure sits between the DEFINE CLASS form1 and its END DEFINE. So the procedure belongs to the form but refers to properties of the button with "This".
This does not fit well in the way OOP is implemented in .Net.

If we would have to keep the code unchanged, so if the event would still refer to the button as 'This' then we would generate an extra class (nested inside the DEFINE CLASS form1) and would move the code for the Click event inside this class:

Code: Select all

DEFINE CLASS btnFirst
        PROCEDURE Click
		this.Caption = "I was clicked"
	ENDPROC
END DEFINE
The alternative is to keep the procedure as part of the class definition and make some changes to the code. For example:

Code: Select all

      PROCEDURE btnFirst.Click
		ThisForm.btnFirst.Caption = "I was clicked"
	ENDPROC
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
Post Reply