There are a number of RTTI-related technologies available in Delphi. The fact that every class is derived from TObject means that there are some methods generally available to each class, such as className, which returns a string with the name of the class of an object. The Delphi compiler generates RTTI for published properties (but not public properties).
The ClassInfo function returns a pointer to the RTTI information
for a class.
RTTI provides an easy way to determine if an object's type is that of a particular class or one of its descendants. The is and as operators provide access to the RTTI and can be used to provide generic routines ie.
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
anEdit : TCustomEdit;
begin
if ActiveControl is TCustomEdit then
begin
anEdit := ActiveControl as TCustomEdit;
anEdit.SelStart := 0;
anEdit.SelLength := length(anEdit.Text);
anEdit.CopyToClipboard;
end;
end;
Note: the text in the edit control must first be selected before the
CopyToClipboard will work. Normally, the user selects the text using
either the mouse or the keyboard but here the code selects all the text
regardless of what the user selected.
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
Edit2.SelStart := 0;
Edit2.SelLength := length(Edit2.Text);
Edit2.PasteFromClipboard;
end;
The above code will copy the text in any control descended from TEdit
and then paste it into the named edit control. It demonstrates the use
of both the is and as operators. Add both a TEdit and a TMemo
to a form and place the above code in the OnClick event of two speed
buttons captioned Cut and Paste respectively and play around.
The Delphi Visual Component Library uses the run-time type information generated for published sections to access the values of a component's properties when saving a loading form files. Furthermore, the Delphi IDE uses a component's run-time type information to determine the list of properties to show in the Object Inspector.
Certain low-level VCL procedures and functions require run-time type information pointers as parameters. The actual format of the run-time type information is internal to the compiler and may change between releases.
In Delphi 3, the generation of RTTI is controlled by the $M (or $TYPINFO) compile directive. The Delphi 3 help file states that any component derived from TPersistent will have RTTI information. However, you can generate RTTI for other classes by using the directive prior to its definition.
RTTI is poorly described in Delphi. The only available information is the
interface described in TYPINFO.PAS. Fortunately, others have documented
the mechanics of calling the RTTI methods notably Ray
Lischner in his book Secrets of Delphi 2. For further information you could search for
RTTI and Delphi in Google Groups
for this.
For example, if you wanted to build a listbox containing the names of
say the TPenStyle you could do the following:
uses typinfo;
var
a : integer;
begin
for a := Ord(Low(TPenStyle)) to Ord(High(TPenStyle)) do
{$IFDEF WIN32}
ListBox1.Items.Add(GetEnumName(TypeInfo(TPenStyle),a));
{$ELSE}
ListBox1.Items.Add(GetEnumName(TypeInfo(TPenStyle),a)^);
{$ENDIF}
end;
By the way, the '^' must be added to the source if you use Delphi 1
compiler but is not necessary in Delphi 3! I am unsure about Delphi 2 -
try it and let me know. Also, the TypeInfo function is not documented
in the Help files (either Delphi 1 or Delphi 3) but returns a pointer.
It is used occasionally within the VCL.
This technique has the advantage over the old hard-code the values as it is quicker and does not need to be changed if the new pen styles are added. Other procedures are available to get and set the property values.
This is quite useful to perform the same action (say setting the colour) on all components within a parent control. Have a look at Using RTTI with properties for a more detailed notes on how to use RTTI to set the colour of a control.
The ability to save and then restore the properties of components on a form is the sign of a user-friendly application. When this sort of application starts, the visual controls contain the same information when the application was closed. There are numerous techniques available to achieve this usually involving either .INI files or the Registry.
If you have a masochistic streak, code can be written in both the FormCreate and FormClose events to save each individual field or special components written which subclass the existing components and save the required values.
The next step in this process may now be obvious - use RTTI. Thankfully the JEDI Project has a excellent implementation of this - a series of components TJvStorage, TJvAppIniFileStorage, and others.
RTTI allows allows access to all published properties on a form. My next example allows the investigation of these for the project. Have a look at the form titled Property Explorer Version 2 which demonstrates each form within the project and then the components and properties within. Given that RTTI contains all the properties and methods, it would seem possible to write an expert to generate the RTF (Rich Text Format) source for a component help file but this is beyond the scope of this presentation.
Last Revised:
Copyright 1998-2007
gra...@pcug.org.au