Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Adding a property to EVERY base class

Status
Not open for further replies.

Mike Lewis

Programmer
Jan 10, 2003
17,511
Scotland
In thread184-1826292, Chris proposed an interesting idea, but it was one that required a certain method to be present in every object based on every VFP base class. The trouble is, as Chirs pointed out: "I can't write a parent class of which both a container and a textbox (and a listbox, editbox, grid, etc) can inherit." In other words, if you want to add the same property or method to controls based on different classes, you have to add each one individually, which is tedious and error-prone.

I'd like to suggest a partial solution.

Like most of us here, whenever I start a new project, I like to create a class library containing a "first generation" sub-class of each of the native classes. These sub-classes start out being the same as their respective parents, with the minimum of changes to their properties, events or methods. That way, if you later need to introduce some change to all the objects based of a given parent, these sub-classes will provide a way to do so.

Long ago, I wrote a simple program to create this first generation class library automatically. The following is a simplified version of that program:

Code:
* Creates a first-level subclass of all (or most) of the 
* VFP base classes.

lcRootLib = "RootClasses.vcx"

* Get alist of the names of the base classes
ALANGUAGE(aBase, 3)

FOR lnI = 1 TO ALEN(aBase)
  lcBase = aBase(lnI)
  lcName = "Root" + lcBase

  * Create an object based on each of the base classes.
  * We error-trap this to avoid problems caused by the
  * few base classes that do not have the relevant methods
  * (OLEBound, OLEContainer, Empty, and possibly others)
  TRY 
    loObj = CREATEOBJECT(lcBase)
    * Save it as a new class
    loObj.SaveAsClass(lcRootLib, lcName)
  CATCH
  ENDTRY 
ENDFOR

Going one step further, it is possible to add one or more common properties to every one of those new classes. You just insert the required loObj.AddProperty() calls between the CREATEBOJECT() and the loObj.SaveAsClass().

Although this will add common properties, you cannot use it to add common methods, and so won't meet Chris's requirement. I can't off hand see a way round that. Nevertheless, I am posting this code in the hope that it might be useful in other situations.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike, you could also add methods, if you first just create the VCX with the unmodified base class then MODIFY ...NOWAIT them and use ASELOBJ() to get an object of the designer, use obj.WriteMethod(), etc.

It's not possible with objects instantiated, they have to be in designer mode and with the class designer open, but that's doable that way. You also get there creating a builder, but that has more complexity than just using MODIFY and ASELOBJ().

The problem I have with this kind of generation is that you have to repeat this every time you want to make a change of code when inheritance would allow you to just edit the code and it is inherited in everything else.

I see a compromise of this to define a template class this generator always uses to make the same changes to all base classes as have been done to the template class. I'd skip doing this for ActiveDoc and Control, but that's a matter of taste.

The last hurdle that remains is also replacing all uses of native base classes with classes from this vcx your code generates, or even further subclassed control classes. But going back to the origin of all this ideas, a grid hover container class, it's obviously not the task of the developer of such a helper class to modify an existing project to be able to use the SetAll approach. To be able to do this, you'd need to generate this vcx of new base classes and then go through all forms and classes of the project to adapt it to these base classes and that's not practical.

Ideally, the VFP community would adopt this design pattern, now including more base modifications, too, but then you also have to overcome the problem, if someone decides to make modifications to classes of this baseclass.vcx that are wanted to be inherited in every other subclass, too. A regeneration with updated code and properties of a template would interfere with that, so you'd need yet another level of subclasses for this kind of adjustments, so they don't interfere with each other.

I don't want to get to the point where I'd be forcing requirements on every developer to be able to use my classes, so that's not a practical solution. My idea of a base container class every other control inherits from falls into the same category, though, no doubt about that. That's why I said I wish there was a way to superclass something. I guess it would not be a very safe concept though. In the wrong hands, intentionally or not, it could do more harm than good.

You can always adopt these ideas for your own projects, no problem with that, of course. If you program based on the requirements your own base classes fulfill, your classes will just not be as easy to deploy to other developers projects, which lack the prerequisites.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top