Important Note for VPE-VCL Users

<< Click to Display Table of Contents >>

Navigation:  dycodoc Template Processing > VPE Object Processing >

Important Note for VPE-VCL Users

Previous pageReturn to chapter overviewNext page

There is a problem in Object Pascal: It does not manage references to objects with garbage collection, like Java or COM do. Garbage collection means that Object Pascal itself would keep track how often an object is referenced and that it would free automatically the object if it is no longer referenced.

Because Object Pascal does not provide garbage collection, it is impossible for the VPE-VCL to create each time a new object when you retrieve one - or you would be responsible to destroy it each time.

Example:

var Tpl: TVPETemplate;

 SomeObject: TVPEObject;

 

SomeObject := Tpl.FindVpeObject('some object');

The above code retrieves a VPE Object from the template. Internally, the VPE-VCL calls the VPE-DLL, retrieves a handle (this is a LongInteger) of the VPE Object in the DLL and stores the handle in a permanent TVPEObject.

Afterwards we execute the following code:

SomeObject := Tpl.FindVpeObject('some other object');

Another VPE Object is retrieved from the template and the handle retrieved from the VPE-DLL is stored internally again in the same permanent TVPEObject as above.

We decided to do so, because if the VPE-VCL would create each time a new object instead of using the same object, you would need to keep yourself track of all objects and you would need to destroy each yourself when it is no longer needed.

 

This is no problem, as long as you keep the following in mind:

Each TVPE class encapsulates an object of the VPE-DLL by storing and using its
DLL-Object-Handle.

Methods and properties of a TVPE class which return any TVPE object use internally one and the same permanent TVPE object to encapsulate a DLL-Object-Handle.

The above rule applies to all TVPE classes except for the TVPEngine class when it returns a TVPETemplate Object, i.e. the method LoadTemplate(). Each call to LoadTemplate() creates a new object. Template Objects are destroyed when the associated VPE Document is closed or when the VPE Object is destroyed.

Implication: the following code is not correct.

var Tpl: TVPETemplate;

 SomeObject: TVPEObject;

 SomeOtherObject: TVPEObject;

 

SomeObject := Tpl.FindVpeObject('some object');

SomeOtherObject := Tpl.FindVpeObject('some other object');

SomeObject.PenColor := COLOR_GREEN;

Due to the mechanisms explained above, SomeObject and SomeOtherObject keep a reference to one and the same TVPEObject in memory: the first call to Tpl.FindVpeObject('some object') did set the DLL-Object-Handle of the TVPEObject to the value of SomeObject. The second call to Tpl.FindVpeObject('some other object') did set its DLL-Object-Handle of the TVPEObject to the value of SomeOtherObject. As a result SomeObject and SomeOtherObject both hold the reference to one and the same VPE Object in the DLL.
Therefore SomeObject.PenColor := COLOR_GREEN will set the color of 'some other object' to COLOR_GREEN, which is not intended.

 

The following code is correct:

var Tpl: TVPETemplate;

 SomeObject: TVPEObject;

 SomeOtherObject: TVPEObject;

 

SomeObject := Tpl.FindVpeObject('some object').PenColor := COLOR_GREEN;

SomeOtherObject := Tpl.FindVpeObject('some other object');

In the above code we work immediately with SomeObject and later with SomeOtherObject.

 

But of course this will not satisfy all of your needs, for example the following code would be impossible to realize:

SomeObject.PenColor := SomeOtherObject.PenColor;

 

In order to solve this problem, we implemented a CreateCopy Constructor for each kind of TVPE class (except TVPEngine and TVPETemplate). The following code is correct :

var Tpl: TVPETemplate;

 SomeObject: TVPEObject;

 SomeOtherObject: TVPEObject;

 

SomeObject := Tpl.FindVpeObject('some object').CreateCopy;

SomeOtherObject := Tpl.FindVpeObject('some other object');

SomeObject.PenColor := COLOR_GREEN;

.

.

.

SomeObject.Free;   // do it by code, copies are not destroyed automatically

In the above example we create a copy of the TVPEObject and assign its reference to SomeObject. So SomeObject references a different separate object and the code
SomeObject.PenColor := COLOR_GREEN will work as expected.

Please note that we call "SomeObject.Free" at the bottom of the above procedure in order to avoid memory leaks. This is very important.

NOTE: You need to destroy each object created with "CreateCopy" yourself when it is no longer needed!