Please enable JavaScript to view this site.

KOL/MCK - User Guide

A much more serious topic is the development of your own visual object. It should be noted right away that it is not customary in KOL to create such visual extensions simply because you wanted to slightly tweak the setting of the initial properties of any existing visual component.

 

I remember the early days of Delphi's triumphant march. Every aspiring programmer was happy to take advantage of the incredible simplicity of the new mechanism for creating their own components: hundreds of "round button" or "light bulb" components appeared. More often than not, there were much fewer really useful components that really extend the capabilities of the standard library.

 

Initially, many developers of visual components took the path of "embedding" the TControl visual object inside its successor from TObj. But this method is fraught with the fact that the "component" formed in this way will not be able to provide all the necessary levers to control the object, hiding its renderer inside. Or you have to write an incredible amount of code that will provide access to all the necessary properties of the new visual object. Or, to expose the TControl object to the outside through a property or a field open to all the winds, which is also not very nice (And the call to any property will now look like MyObj.Control.Width, eg).

 

Another problem that arises when using the method of "injecting" a TControl object inside its inheritor from TObj is the problem of correctly deleting used objects. You can add your object to the parent using the Add2AutoFree method, but then you cannot directly destroy it using the Free method or the Free_And_Nil procedure: when the parent is destroyed, the destructor will be executed again, and the program will most likely break at the exit. It is more correct in this case to add the container object to the list of objects of automatic destruction of the most controlled visual control included in it. And then it will be possible to destroy it by calling either a special method of the enclosing object, which will call the Free method for the control, or provide direct access to this control in its descendant TObj,

 

Unfortunately, there were even "tutorials" and the first visual extensions using this technique of embedding inside TObj before I made the necessary efforts and sent component creativity on the right track.

 

The correct mechanism for creating your own visual extension is inheritance after all. If a fundamentally new visual element is created that is absent in the library, then it must be inherited from the TControl object, and if an existing extension is used as the base one, then it must be inherited from it. Although, in life, examples of inheritance from extensions have not yet been noticed (which, by the way, is not bad at all for the purpose of saving application size: the lower the hierarchy level, the less memory is allocated for virtual method tables).

 

But there is one "BUT" here. Unlike VCL, KOL does not use virtual constructors. It is customary here to define NewXXXX functions (parameters) for constructing objects. It would seem, so what: we create a new type of object, write a function for it NewMyControl (…): PMyControl and ...

 

And here the problem begins: what to write in the code of this function, if the creation of the TControl ancestor object should be at least the _NewControl function, and it can only create an object of the TControl type, but not its successor.

 

In fact, the problem arises only if new fields are added to the inherited object (not to mention new virtual methods, practice has shown that you can do without them just fine). If only non-virtual methods are added, then the problem is solved very simply: it is enough to call _NewControl inside your constructor, and return exactly this result at the output, casting it to the required type (PMyControl). Unfortunately, creating a truly new object is almost never complete without adding new fields, so the problem persists.

 

As a result, the following convention was adopted: for an object inherited from TControl, new fields are added through an additional structure or object, for which the CustomData and CustomObj properties are used.

 

You can use either the CustomData property (if a simple structure is enough to store new fields), or CustomObj (if you want to get some kind of benefit from the object as a keeper of new fields), or both (but usually one of them is enough). When an object of type TControl is destroyed, its CustomData and CustomObj fields are destroyed automatically, and the FreeMem function is used to delete the structure pointed to by CustomData, and the Free method is used to destroy the CustomObj object.

// Note: The benefit of using the CustomObj object may be, at least, the ability to define its own destructor for it, in which any other resources allocated during operation will be freed //.

 

As a result, the number of fields of the TControl object in the descendant does not change. This makes it possible to do the same as in the previous case: in your "constructor" NewMyControl, call the _NewControl function to construct a visual object, and at the output, cast the resulting object to the type PMyControl...

 

An additional plus of this approach is that your extension continues to use the same single table of virtual methods of its successor TControl (we have already agreed that you will not add new virtual methods, otherwise the above trick is impossible). This means that the increase in the code will occur only by the size of the code of the new methods used in the application.

 

And, as I said before, there is a certain amount of reading material specifically for those who wish to create their own extensions, visual and non-visual. You can find them on the KOL and MCK sites, as well as numerous examples of such extensions. So I will take the liberty of reducing the length of this document and avoiding unnecessary duplication of information.

 

KOL / MCK User Guide - Created by Carl Peeraer - Diamant Soft, based on the work of Vladimir Kladov - Artwerp.be

  

Keyboard Navigation

F7 for caret browsing
Hold ALT and press letter

This Info: ALT+q
Nav Header: ALT+n
Page Header: ALT+h
Topic Header: ALT+t
Topic Body: ALT+b
Exit Menu/Up: ESC