Going back to the idea to "flatten a class hierarchy": You don't have that option itself, but there are several options other than subclassing.
Just note once again, an SCX is not really much easier to handle. You do [tt]oForm = CreateObject("formclass")[/tt] and [tt]oForm.Show()[/tt]. Put these two lines into a DoForm function and you can run your forms with one call, too. You just need to keep oForm alive for the form not to vanish after the oForm variable releases. So if you don't have a form handler, that's the time to create one. The main job of a form handler will be to manage and store form references, starting a form is just one job, knowing all running forms, and when asked to start a form deciding to do so or return a reference to the already running form is one of the advanced tasks, but surely keeping form references is a base task. And that's most easily done by storing them into a collection, which then is the only object needing to be kept alive. VFP oes exactly do that with it's _SCREEN.FORMS array/collection. It's a native thing that existed way before collection, so it's not based on some fox class, bu essentially it is a collection.
Back on the topic of trying to flatten class hierarchy into one file: As I don' know the findCustomer class, I can't tell you how hard or simple trying to flatten class hierarchy and get rid of it might be. If this form class is based on the native form and its controls also are native, there's nothing to flatten and loForm.SaveAs() would work, though it never gives you exactly the corresponding SCX, as init then already has run and you save properties etc in the state they are in the moment of saving:
Code:
o = CREATEOBJECT("form")
o.Caption="Test"
o.SaveAs("MyForm.scx")
MODIFY FORM MyForm.scx
You're in the form designer and that SCX form has the caption "Test".
So code depending on initial values by using the ResetToDefault() method could fail, but that's almost never a hard problem. You may get closest to the original when putting a SaveAs into the load event, but I'm not sure if that would work, no controls of the form are available at that moment, so you most likely end up with an empty form only containing all user-defined form methods.
One way to save the form as is would be making use of ASELOBJ() when having the form open in the class designer and then SaveAs that object. I won't show how to use that in detail, as that ends up the same as [tt]CREATE FORM AS findCustomer Of CustomerForms.vcx[/tt] does, so use that. Or use saveas, as it likely get's you close enough when init doesn't do much anyway.
But there is another simple way if you don't want to fiddle with the original class but have it as the starting point for your edits: Copy the class. As undesirable copies are in the sense of OOP code reuse, that'll give you the chance to vary from the parent class of the findCustomer form - maybe a general findSomething form class - and at the same time don't go back to the initial state of that parent class but start at the stage the findCustomer form is at. So actually a copy of a class also is an inheritance and subclassing, but it subclasses the parent class and copies over the current state of the class, which you copy.
And copying a VCX class is simple. Create a new empty VCX ideally named in a way it appears next to the class library containing the findCustomer form in the project manager. Now simply drag&drop the findCustomer class there. Now you see why I asked you to name the new VCX alphabetically close. You can also drag&drop across project boundaries into any class library of a separate project you have open in a second project manager. You can now rename the new VCX, nothing depends on its name yet, and you must rename your class copy, or you risk on CREATEOBJECT('findCustomer') starting your form copy instead of the original. That copy process, of course, creates the same dependencies on parent classes as the findCustomer form has rooted in the VCX of the findCustomer's parent class library anyway. After renaming th findCustomer form class, you might also drag&drop it back to its original VCX library to exist side by side to findCustomer.
If that form is based on the native form, you don't have a direct parent class dependency in your copy, but then you still might have references to control classes on the form. You'll not strip off dependencies anyway and shouldn't want to strip them off, the whole purpose of classes is to reuse code and not redo everything from scratch.
A much more straightforward way of copying a form to some new project will be to copy all base VCX libraries from the old to the new project, meaning to reuse the same class hierarchy. That gives you a chance to not only edit this class but refactor the whole class hierarchy aka framework of the project without affecting the old project. All the parent class libraries are what you need to support a class copy you did with drag&drop, too, anyway, if you want to become independent on the old project. That way of copying the whole project structure into a new project home is possible, as references are stored in relative paths.
That problem is none, if your new form should belong to the same project, you shouldn't want to decouple from all that hierarchy within the same project, inheritance is good and it's all established and will work.
OK, at this point I think I established enough awareness of not being able to really flatten the class hierarchy of the form and all its content, yet aside from these possibilities, Steven Black has thought of a tool to extract all the essential parts as share utility. You find that on
This is not the way I would recommend to work, no matter if within the same project or a new project, as that collects all dependencies into one "big ball of gum" VCX, but it's a way to share a single class with someone without needing to copy a whole project libs just to not forget some dependency. It has its boundaries on dependencies not detectable when they come in by macro substitution or any code creating objects at runtime. And it still doesn't flatten the whole thing into one class, it just pulls together all parent and grandparent stuff in one VCX. And it keeps it at the VCX level. To be fair it is the best option for sharing code without needing to share a whole framework and so it deserves its name and is good for its purpose.
And after all that, of course, your normal way of acting in an OOP project is to inherit from findCustomer or its parent form class. I can't tell you which way you'll be better off. To summarize the options:
1. When you start at the parent class level and still want almost the same behavior and composition as the findCustomer form has made, you have to redo a lot.
2. If you, therefore, inherit from findCustomer itself you have all the work done, but now can't edit things inherited, only call them by DODEFAULT or overload by writing new code.
3. The copy, as the third option, gives you a parent class inheritance with all the things added and modified in the findCustomer form at your disposal to change, maybe the best compromise, still not an SCX.
4. To get a similar result as 1 in an SCX CREATE FORM with the class options and specify the
parent class of findCustomer.
5. CREATE FORM with the class options specifying findCustomer and you have a findCustomerSCX which compares to 2.
6. Instantiate findCustomer and SaveAs you finally get an SCX comparing to 3 minus some fiddling with the effects the Load() and Init() had.
All these options won't remove control class dependencies and other parent class dependencies, though. It was never the intention of any OOP concept to enable that kind of refactoring.
And since the options4-6 are less known and even less often used, developers get the idea SCXes leave you with the most freedom o editing and modifying forms, yet they only give you as much freedom, as you normally base an SCX on a native empty form, so everything on it was created from scratch. It's not the best way to optimize your work time. The need to edit or even remove parts of a class-based form or subclass form is pointing out the parent class has specialized too early with something turning out to not be necessary for all child classes and your class hierarchy is too flat for that matter.
Besides the technical problems of a not so well thought of class hierarchy, you might also face the copyright problem of inheriting from a paid framework. It should never become a problem within a company having bought that framework to also use it in other projects, but it can become a problem in contract work where you're faced with not illegally reusing something for customer A in a customer B project based on no or another framework. Then you have a business problem on top of a technical one. I'll just scratch that, as you say "as this form contains table references, I am getting issues." That problem is most likely more of a code problem than an inheritance problem, as a form class has no data environment you could inherit or copy, you inherit/copy code the form uses certainly also for data access. To be able to change that using other tables the copy option is your best choice.
Bye, Olaf.