An Alternative New-Class Window
This article first explains the reason of existence of an alternative New-Class window I have written. In the second part the applied principles are explained.
Why We Need an Alternative New-Class Window
When you type ‘CREATE CLASS ?’ in the Command Window, the native New Class dialog window will pop up and after having filled in only three fields a new class can be created. The required fields are
- the class name
- the class it must be based on; in other words the parent class
- the classlib that it must be stored in.
That’s all and that’s simple. But I think it is a little bit too simple. Why? It is the class name that troubles me. All text books and all gurus tell us that we must pay special attention to the name of a class. It should be created according to a scheme, a philosophy. For example, the scheme may prescribe that any class’s name starts with certain characters and/or contains a reference to the type of class.
Perhaps you say now: “Agree, but that is possible with the native New Class window, isn’t it? So, what’s your problem!” The problem I see is that it may be hard to understand and/or apply the scheme. Moreover, a developer in your team may show a lack of discipline. Of course, you might consider to fire that developer. But perhaps this person has other talents that you highly appreciate.
In the long run a myriad of inconsistent class names may have been created. By that time the names in your classlibs appear to be a mess and you start to have problems remembering their purpose.
What I have done is create an alternative New-Class window that creates the class name for you, based on some choices you have to make. Actually, it is a wizard, although all steps are in the same window. Moreover, there is code that enables you to integrate the window in the Project Manager. Whenever the developer chooses New (Class) in the Project Manager, the alternative window will be invoked instead of the native window.
“Fine”, you may think, “but according to what scheme is the name created? Is it according to the scheme that I use?” The scheme I have applied is explained in the next paragraphs. Some elements can be adjusted by you and even their order can be changed. I hope that this flexibility is enough for your requirements. If it is not, then perhaps you may decide to modify some source code. Of course, in that case the drawback will be that updates of my alternative won’t be of much use to you. If your philosophy is entirely different from mine, well then perhaps you should write your own alternative New Class window.
The Applied Principles
Okay, what’s the scheme that I propagate? Here are the elements that will make up the name:
- A My Classes Descriptor
- A Class Type Descriptor
- A ‘Based On Class’ Prefix
- A Further Class Descriptor
- An Abstract Class Descriptor
The order of the elements in the class name can be changed, but here in this documentation the default order is presumed.
The My Classes Descriptor (referred to as Classes Descriptor in the New Class window) will be the first part of the name. It defaults to ‘my’, but it can be changed. Choose ‘Browse NewClass table’ in the window and add, edit or delete Type 1 records. In the New Class window you can choose any from the Type 1 entries that have been created. Your preference is stored in the Resource File, unless there is only one entry defined in the NewClass table. If you don’t want to use this descriptor, then simply delete records of Type 1.
The Class Type Descriptor is a ‘prefix’ that comes directly after the My Classes Descriptor. It ensures that you recognize the class type easilly. Type in ‘object naming conventions’ in the VFP-help to get the list of prefixes that is used here as the default. Each entry can be changed by choosing ‘Browse NewClass table’, even to an empty string.
The ‘Based On Class’ Prefix is the first part of the name if the class must be based on another class, the parent class. In that case, the items 1 and 2 are not tested for, because they are supposed to have been incorporated yet in the name of the parent class.
The Further Class Descriptor is the text that is added to the right of items 2 or 3. It is free text that is obliged sometimes, optional other times and not even available in case you are creating an abstract class based on a VFP base class, that will gonna be the base for all your classes of that type. Take notice that there is no profit from naming the class type in this part of the name. Also, if it is an abstract class, the advice is to keep the descriptor short.
The Abstract Class Descriptor will be the last part of any name that will be used only as the base for other classes. In other words, it will be used for abstract classes. The descriptor defaults to the underscore, but this too can be changed by choosing ‘Browse NewClass table’, even to an empty string. This descriptor ensures that you recognize abstract classes easilly.
There is one more thing that the wizard asks you to fill in: a description. The classlib has a field Reserved7 for this text. It is also shown in the Project Manager when you select a class. For your convenience, the wizard will add its own text if it is an abstract class.
The checkbox “Ignore ‘Based On Class’ Prefix” can be used for instances that the ‘Based On Class’ Prefix is not what you want to appear in the new name. This is especcially true if you base the new class on some old class that has not been named in accordance with the proposed scheme.
In case you choose to ignore the ‘Based On Class’ Prefix, the Further Class Descriptor will be used as the (whole) Class Descriptor. In that case you should seriously consider mentioning a My Class Descriptor and Class Type in the class descriptor manually.
As promised, the order too can be changed. The ‘Browse NewClass table’ opens the NewClass table. It has two entries that deal with the order. They contain templates. The parts of the template are replaced with the chosen values. By changing the order of the parts, the order is in your hands.
These are the defaults of the templates:
| ?MY?CLS?DESCR?SEP | Template for VFP Based Classes |
| ?BASE?DESCR?SEP | Template for Class Based Classes |
And here is the explanation of the parts:
| ?MY | My Classes Descriptor |
| ?CLS | Class Type Descriptor |
| ?DESCR | Further Class Descriptor |
| ?SEP | Abstract Class Descriptor (Separator) |
| ?BASE | ‘Based On Class’ Prefix |
Essentially, that’s all. Examples:
| Parent | Name | Elements | Usage |
| custom | myCus_ | my Cus _ | Abstract class for all my custom classes. |
| myCus_ | myCus_Impl_ | my Cus _ Impl _ | Abstract class for all my ‘Implementator’ classes. |
| myCus_Impl_ | myCus_Impl_Main | my Cus _ Impl _ Main | Concrete class for implementator class on main forms. |
| myCus_Impl_ | myCus_Impl_PlainText | my Cus _ Impl _ PlainText | Concrete class for implementator class on plain text forms. |
| myCus_Impl_ | myCus_Impl_RTFText | my Cus _ Impl _ RTFText | Concrete class for implementator class on RTF text forms. } |
| myCus_Impl_ OR myCus_Impl_RTFText | myCus_Impl_RTFText2 | my Cus _ Impl _ RTFText2 | Alternative concrete class for implementator class on RTF text forms. |
| custom | myCus2_ | my Cus 2 _ | Later created abstract class for specific my custom classes. Obviously, the myCus_ class is no longer for a ALL my custom classes. |
| commandbutton | viaCmd_ | via Cmd _ | Abstract class for OK command button. |
| commandbutton | viaCmdOK | via Cmd OK | Concrete class for OK command buttons. |
| viaCmd_ | viaCmd_OK | via Cmd _ OK | Concrete class for OK command buttons. |
If you understand the examples, you understand the principles and the scheme. If things are still somewhat unclear, then run the alternative New Class Window and save some results to a dummy classlib.
One more remark: The defaults that can be changed, can only be changed if the NewClass.DBF is readwrite. If it is readonly, they cannot, no longer, be changed. This feature enables you to initially change them and then simply change their readonly attribute, thus ensuring that employees can no longer change them.
Integrating it in your Project Class
Part of the solution is the code in CodeForProjectClass.PRG. That code can be placed in the method QueryNewFile of your Project Class, assuming here that you indeed use a project class for your Project Managers.
The routine will call NewClass.app whenever the user selects New (Class) in the Project Manager.
The advice is to place a copy of NewClass.app in the home directory of VFP. If the name NewClass is troublesome for you, then rename the app, dbf and cdx. Keep their prefixes equal. Also do not forget to modify the code in CodeForProjectClass.PRG accordingly.
However, there is one quirck and it’s not the fault of NewClass.app. The native 'Create New Class' window knows the destination classlib. But there is not a single function in VFP that will make this information available to the developer. That’s why NewClass will ask you to specify that classlib, even if you invoked the window via the Project Manager. I apologize for this. If you too wish it should be available to the developers, please send a request to the devteam in Seatlle.