Didier Cabalé Delphi Page

Embarcadero Delphi MVP

Components Programs Tips Games Links

We are pleased to announce that RAD Studio 12 (Athens) has been released

Components & Utils

> Extended TComboBox
I realized that the VCL TComboBox does not expose a OnItemIndexChange property, that is, an event handler that fires *only when the selected item index is changed* either with mouse clicks, or with keyboard down /up keys, or with code.
Thus I built this little extra, making a new extended TComboBox, called TComboBoxExt, that supports a new event-handler property called OnItemIndexChange.
click here for more details

click here for collapsing
  TComboBoxExt = class; //forward
  TNotifyComboEvent = procedure(Sender: TComboBoxExt; const I: Integer) of object;

  TComboBoxExt = class(TCustomComboBox)
    FLastItemIndex: Integer;
    FOnItemIndexChange: TNotifyComboEvent;
    procedure WndProc(var Message: TMessage); override;
constructor Create(AOwner: TComponent); override;
... property OnItemIndexChange: TNotifyComboEvent read FOnItemIndexChange write FOnItemIndexChange;
implementation { TComboBoxExt } constructor TComboBoxExt.Create(AOwner: TComponent);
FLastItemIndex := -1;
procedure TComboBoxExt.WndProc(var Message: TMessage);
if ((Message.Msg = WM_COMMAND) and (TWMCommand(Message).NotifyCode = CBN_SELCHANGE))
or (Message.Msg = CB_SETCURSEL) then
if Assigned(FOnItemIndexChange) and (FLastItemIndex <> ItemIndex) then
FOnItemIndexChange(Self, FLastItemIndex);
FLastItemIndex := ItemIndex;

> Interactive basic viewer
It's a long time I've been looking for a "basic interactive report viewer", inherited from TGraphicControl, with little overhead, and html independant.
Not finding exactly what I wanted from outside, here is what I did:
1. digged into QuickReport components source code.
2. adapted their QRX preview /browser, in modifying the layout.
3. proposed to QuickReport some necessary modifications to their library source code
.. and voilà, here is the interactive report I was after -> Interactive basic viewer.

Want some more details ? download [this].
NB: this demo requires QuickReport 5.05.2 build2 or upper

> TCsvTransform class helper (ver 1.3)

Did'nt you ever need to simply store your data in a .csv (Comma Separated Value) format, then load it in a TClientDataSet and play (CRUD) with it .. and then save it back to the same (or other) .csv file ? Delphi does not provide any built-in access to .csv data, but a TCsvTransform class helper makes it simply come true.
How ? .. look at the example [here]

> TFocusComboEdit controls (ver 6.1)

Like TComboEdit or TDateEdit but showing a side-button displayed *only when the control has the focus*.
Caution : These controls are TJvCustomXxxxEdit descendants and require JVCL /RxLib installed.
version 6.1 supports LiveBindings -> can be used directly assigning TFocusComboEdit to TLinkControlToField.Control property in object inspector.

> TEventsHandler class

enables to run multiple events at once, simulating event multi-casting. example of use :

   aEventsHandler: TEventsHandler;
   // create a new TEventsHandler with 'CreateNextForm' procedure as its main event
   aEventsHandler := TEventsHandler.Create(CreateNextForm);
   // set 'Validate' procedure to be run before aEventsHandler's main event 
   aEventsHandler.AddLinkedEventsHandler(odBefore, TEventsHandler.Create(Validate));

   // set 'ClearStatusBar' procedure to be run after aEventsHandler's main event 
   aEventsHandler.AddLinkedEventsHandler(odAfter, TEventsHandler.Create(ClearStatusBar));

   // run all events at once in the specified order

> Vigenere encoding unit

simple string encoding using Vigenere algorithm

> Ascii2XML utility (ver.1.1)

enables to transform any Ascii /flat file with fixed length fields to a XML file, according the template of your choice.
For using it, follow these steps:

Nb: Requires JCLStrings.pas (from Jedi Component Library) and UParseReplace.pas

> TEditableCtrlHolder (ver.3.3)

TEditableCtrlHolder is a data validator of any 'TEditableCtrl'(1) controls of your TForm. For each of TEditableCtrl, you can set their DataType, MaxLength and NullForbidden property. Check the validity of what you entered into each TEditableCtrl against the properties defined above. You can also loop into all TEditableCtrl to check if the entered values have been modified.
Version2 adds support to RxLib controls (TRxCheckListBox).
Version3 adds a OnValidate event-handler + support RxLib date-time picker controls (TDateEdit and TDBDateEdit)

(1): a TEditableCtrl can be any of editable controls, ie TEdit, TComboBox, TListBox, TCheckBox, TMemo, ..

    For using it, follow these steps:
  1. add EditableCtrlHolder.pas to your 'custom user package', compile your package.
  2. open the demo project

> TAlignedEdit3

derived of TAlignedEdit from Peter Below (TeamB) that enables left, center or right justification of the text in a TEdit. This version enables text focusing when the TEdit becomes active, by removing the multi-line capability.

> TDBTreeView (ver.1.04)

Represents TDataSet records in a standard TTreeView.
click [here] for the screenshot

for a Delphi5 compatible version, click [here]

> TMELabel (ver.3.0)

Like a TLabel component with a MEFont property that sets the font on CMMouseEnter Windows message. Usefull with AboutBox type forms, when you want to link your TLabel with internet.
Nb: may be same component /behaviour as TJvLinkLabel from JVCL

> GETVALUE function for QuickReport

Enable to refer to other TQRPrintable controls (TQRExpr or TQRLabel) to get their value.

Usefull when you don't want to repeat TQRExpr expression every time you want to use it in your calculations.
To use it:

  1. add this unit to your 'custom user package', compile your package.
  2. put a TQRExpr on your TQuickReport, and set it's function property as 'GETVALUE([TQRPrintable name])'.

> Parse & Replace utility (ver.2)

You simply want to parse your html file that contains some custom tags, and replace these tags by the required strings.
When used with TPageProducer, advantage of this method comparing with using the TPageProducer's OnHTMLTag event handler:

[back to top]


Many programs are arleady built. Among them:

> Executive dash-board: severall 'dash-board' based products are available, depending on your power /autonomy requirements:

  1. application fully integrated dash-board: all the reports are integrated in the application code.
  2. selectable dash-board: all the reports are available in opening external files.
  3. 'visual customizable' dash-board: all the reports are available in opening external files. You can build these files yourself with 'drag and dropping' components in a form. No line of code is at this level required.
  4. 'fully customizable' dash-board: all the reports are available in opening external files. You can build these files yourself with a fully independant 'report-designer'. The 'report-designer' enables you to build wysiwyg forms, and to write genuine Pascal-Delphi script on all the event handlers needed. Creating such a report can require development capabilities.
Synoptic of all dash-board's capabilities
Type of dash-board
application fully-integrated selectable visual customizable fully customizable
user's report latitude print /preview
select report no
design report no no
script on report no no no

In anyway and as a preliminary, these dash-boards must be connected to any either specific or open database, the one of your entreprise.

> Scrivitt ™: a program that enables to build standardised letters, simply in adding custom paragraphs.

> Document-Explorer: Store your documents in a folder, and organize them as you wish with my TDBTreeView component.

> Archieve-Explorer: Store your favourite magazines in the programm, and search them with the fields and key-words of your choice.

> BdCC: a front-office configurator to your ERP, and add comprehensiveness and security to your business.

> BCRx: a web application that enable order entry and query +e-mail communication between customer and company.

> Data Dictionnary: a simple data-dictionnary management software. Store your data in the required XML format, and view /filter them in your browser with the required presentation. Implemented with Delphi +XML +XSLT.

> Reminder: don't forget what you and your co-workers have planned !!
1. setup an open and unique database with the events you (or your co-workers) want to be reminded for
2. receive at the right time an e-mail reminding you the event.
NB: for more infos, please contact me

[back to top]


> How to debug a Wizard installed in the IDE 
You could read first the Debugging a Wizard from the RADStudio documentation.
But there are cases where the compiled Wizard is presented as a .dll, and not a .bpl. The advantage vs the .bpl is that, in the case where the Wizard crashes the IDE, you can uninstall this .dll from outside the IDE. The disadvantage is that it's more tedious to issue than with a .bpl.
But how to do that?
1. Create your .dll Wizard, and compile it.
2. Create a "DebuggingTools" registry Key, Computer\HKEY_CURRENT_USER\Software\Embarcadero\DebuggingTools\<version>\Experts, and under it, the following String Value: Name=<WizardName>, Value=<path_to_your_dll>
3. Run a 2nd instance of your IDE, by running the Wizard project, in setting bds.exe as the host application and in setting the host application parameters with -rDebuggingTools.

Once the 2nd instance of the IDE is run, you see the blue compilation bullets appearing in the 1st IDE instance, where you can place your break-points. These break-points can be hit, when playing with the 2nd instance.

> How to debug a component at design-time
When developping components, a question usually raises: how to debug that component at design-time?
I can see two different ways for that:
1. The usual, that is, from the component package project, install the component if not already installed, run a 2nd instance of the Delphi IDE (bds.exe), from the current instance of the Delphi IDE, in setting Delphi (bds.exe) as "Host application". In this way, the 1st IDE instance will use its debugger to debug the 2nd IDE instance, where you'll place your components on the form's designer. This way is officially explained here -> Testing Installed Components
Note that you will need to install the component first in the IDE, because if you don't..well you won't be able to place it on the form's designer.
2. The other way is to send outputs /logs to the debugger (OutputDebugString()) in the component's source code, and use an external debug viewer, such as DebugViewer ( DebugViewer is capable of displaying both kernel-mode and Win32 debug output generated by standard debug print APIs, so you donít need a debugger to catch the debug output your applications or device drivers generate.

> How to mimic a TGraphicControl overlay a TWinControl
TGraphicControl and TWinControl, when they lay on a TForm, always behave as TWinControl overlays TGraphicControl. This, even if you put your TWinControl in the background - context-menu 'send to back'.
Windows is designed like this, and it has good reasons for it..

However, there are case where you want it behaves the other way, ie a TGraphicControl overlays the TWinControl, or at least that it mimics that.
The tip is to capture the TForm image, and set it as a background where you can place your TGraphicControl's

Want to know more? Then download [this demo]

>LiveBindings: how to merge 2 controls property values into a third one 
An usual use-case, using LiveBindings, is when you have to bind 2 controls with each other. Right.. for that, you can use either the built-in, from the LiveBindings designer, "Quick Bindings" TLinkControlToProperty, or a TBindExpression.
But a less trivial case is when you have not only one source control, but several, that you want to be merged in a single target control. Here is where the TBindScope comes in the game. For a quick summary, look at the following picture:

For a simple sample project, download [this demo]

>VirtualTreeView - TVirtualStringTree virtuality, reading a text file
I spent some time to find an article on the web (I once found) dealing about how much a VirtualTreeView - TVirtualStringTree ( control was.. virtual. :-)
As I did not find it again, I created it..
TVirtualStringTree is "virtual" in the sense that it decouples the data it is showing from itself, at its maximum. That is, it binds with the data only when it displays it.
This demo shows how it does it:
The TVirtualStringTree basically reads lines from a large text file, and from that, compare its behaviour with a basic Win32 VCL component, the TTreeView in terms of:
1. time for loading performance.
2. memory consumption performance.
Then, look at the sample demo code, and you'll see that the load and display abstractions are quite surprising..
Download [this demo]

>Handling .pas and .dcu files in IDE

4 options

Project's source


Project's options


IDE options



browse units @ design

path to .pas

cf compiler search path (if can compile, can browse)


cf debugger source path (if can debug, can browse)

Library Browsing path to .pas


where to find units

Compiler search path to .pas

Compiler search path to debug .dcu

Library path to .dcu's

where to generate .dcu's

Unit output directory

no .dcu's generated

no .dcu's generated

where to generate .exe

Output directory

debug units @ run

compile with debug infos

Debugger source path to .pas

compile using debug .dcus

Debug DCU path

Reference to units in .dproj

<DCCReference Include


<DCC_UnitSearchPath>, <Debugger_DebugSourcePath>



.dpr used units is parsed

 [options]: -I<path to .pas>

[options]: -I<path to .dcu>

[options]: -I<path to .dcu>

[options]: -O<path to .dcu>

[options]: -O<path to .dcu>

[options]: -R<path to .dcu>

[options]: -R<path to .dcu>

[options]: -U<path to .dcu>

[options]: -U<path to .dcu>

Compiler search path must reference debug .dcu's

>TListView OwnerDraw
The VCL TListView control, due to its Windows native origin, displays somewhat unexpected renderings, when it's about showing images next to the text. Look a the following picture:

What can we see?
- 1st, a white empty space to the left of the 1st column text
- 2nd, a white background around the pictures
- 3rd, the picture color changes according if the item is selected or not
But that is not what I want! Why, though the Item's Image is none (Item's image index to -1), there is still place left for the image? why though the image is set with transparency, it is shown with a white rectangle surrounding it? why the images when focused change their color?
All this is handled natively by the underlying windows control. And the only way to get a more "normal" behavior, is to draw this yourself, in the TListView.OnDrawItem event handler.
Here is the expected result:

The other solution you have to get rid of the white empty space before the TListItem's Caption is to set it's Indent property to -1.

Want the details? download [this demo].

>Application Tethering
Reading data from one application to another is a trivial need in today's world, where it is more and more matter of decoupling, sharing, open-access of a single application or between two or more application.
Before RADStudio XE6, for achieving this, we needed what we called "Interprocess Communication" routines, based on the current OS Messaging system. (On Windows, we have the function SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM))
From RADStudio XE6 on, we can get rid of this OS dependant routines, by using the new Tethering controls: TTetheringManager and TTetheringAppProfile.
We can now use these controls for building a simple client /server application group, that shows the different ways how a client application can receive data from a server application:
1. the 'passive' way: the connected client receives data sent by the server
2. the 'request' way: the connected client requests for data, and receives them from the server.
3. the 'observer' way: the connected client is observing for data change on the server, and if they change, it reacts to the event.
Want to know more? download [this demo].

> TTask vs TThread
RAD Studio XE7 came with a very interesting RTL new feature, the "Parallel Programming Library" (PPL).
But why moving from the existing TThread to it?
Mainly because it eases the development of multi-thread /task operations:
1. Better integration with the application main thread.
2. Automatic memory management with interface implementation.
3. Heritage not needed.
4. Code more compact.
Want some more details? download [this simple demo].

> How to adjust colums /rows to the grid's size? 
When you create a TCustomGrid descendant (TStringGrid or TDrawGrid), the required colums and rows are never adjusted to the grid.
If the grid is too wide /high for the contained cells, an empty space remains to the right /bottom of the grid.
If the grid is too narrow /short for the contained cells, the cells are truncated /hidden and accessible using the direction keys or the scroll-bar (depending on the ScrollBar property).
If you want that all the cells precisely fit their container grid, then you will have to set two properties:
1. ScrollBox := ssNone; because the scroll-box is useless in this case
2. ClientWidth, and ClientHeight set to the size of all internal parts (cells, grid-lines, ..)
Note: ClientWidth /ClientHeight is representing the size of the internal border of the grid.
The result is shown as following:

> Why Getters and Setters for Properties? 
I very often read /write the following when declaring Properties:

    property MyProperty: Integer read FMyProperty write FMyProperty; // Properties without accessors - getters and setters -

Well .. that seems easier and sufficient at first glance.
But there are some reasons why you should use getters and setters.
Want some more details? download [this simple demo].

> Class helper for TComboBox 
A colleague asked me if the new Delphi XE5 improved the TComboBox in adding, to the underlying string list, an other linked list of whatever type.
"What for?" did I ask.
He replied "because I don't want the underlying list be limited to *only a list of string*. The selected string should be linked to whatever else I want (integer, object, ..)".
I replied ".. but you can do that, using a TObject with method AddObject('a string for my combo', MyObject), and now you have an object linked to your string".
Ok, he said, but for handling the 'setting' and the 'getting' to /from this object, I need a new component with an item accessor by the object. Moreover, the AddObject method is too vague if one want to add an integer only (not an object)".
I replied "If it's just what you need, then you should avoid creating a new component just for that : you should consider the use of a 'class helper for TComboBox'".
Want some more details? download [this simple demo].

> Pointers ? Why still using them ? 
Pointers are nowadays rarely used by Delphi programmers, but they are still usefull.
When you need to read information from dll's, it's frequent the dll provides access to its data through pointer variables. The data you are accessing can be of any type (simple, complex, class, ..), provided its length is known by the compiler (ie no dynamic types like "String" or dynamic arrays) .. but there are workarounds to this limitation.
Want to know more? look at [this simple demo].

> Vanishing /unstiking component property value issue
Have not you ever been in the situation where, from the IDE, you set a property value for one of the component used, then test your program, be happy with it, save it, then re-open it ... and noticing that the value that you set for your component's property has changed ?
Here can be the reason:
1. if you set from your IDE the same propertie's value as the default one, then Delphi will not save the value in the .dfm at the time you will save your project.
2. the problem raises when you re-open your project : as no propertie's value is specified in the .dfm, the propertie's value that will appear in your object inspector is the one set in your component's constructor (if one set), or the default for the propertie's type.
When you build your own components and you want to set default for properties, be carefull to be consistent with the value given in the constructor.
Whether you use your own components or third party components, one good way to notice this trap, is to closely look at how properties are displayed in the object inspector. If the values are displayed in normal weight font, it means your propertie's value fits with its default. If the values are displayed in bold font, it means your propertie's value differs from the default, or that no default have been set.
Thus, when you first drop your component on your form, have precisely a look at a property displayed in bold, and that becomes in normal weight when changing manually its value.

> LiveBinding TObject 
Delphi is an IDE that enables OOP (Object Oriented Programming) and designs the user interface. Hence why not presenting the evidence : "editing TObject instances on a form".
Object (TObject's instance) can be of a simple TObject class, or of a more complex type like a TObjectList<T>. The UI controls that will handle the display do not need being data-aware controls.
LiveBindings makes this possible, using TBaseObjectBindSource descendant.
Downloadable demo project group (below) shows :
- simple object (TObject) binded to control - FireMonkey project -,
- object list (TObjectList<T>) binded to control,
- two object lists (TObjectList<T>) linked in a master /detail relation, both binded to a TStringGrid.

Want some more details ? download [the demo project group].

> import /export with XML 
The question is quite frequently asked all around and is sometimes answered with complex structures /process .. and the question is : "how to import XML data in my RDB (relational database), then edit them (CRUD -create, update, delete-) using standard UI controls, then export them back to a potentially other XML format ?".
Of course the question can be only any part of the above, ie "how to (only) import from XML" or "how to (only) export to XML".
The answer is quite simple if you use standard VCL components /structure, that are:
For accessing data: TSQLConnection, TSQLDataSet, TDataSetProvider, TClientDataSet.
For transforming data: TXMLTransformClient or TXMLTransform.
For displaying data: either data-aware controls (TDBxxx), or standard VCL UI + LiveBindings controls.

Want some more details ? download [this].
NB: this demo requires SQLite dbExpress driver provided with XE3 Professional (or higher)

> deFocusControl data event in LiveBindings
Posting a record with a null value for a required field fires a 'database error' exception. Before this exception is being fired, a procedure TField.FocusControl; is executed. The intention behind that is to set focus on the UI control linked with this TField, highlighting it for further correction (ie or cancel the edit, or post a non null value)
LiveBindings does not support the deFocusControl data event (ie procedure FocusControl(Field: TFieldRef); is absent in Data.Bind.DBScope TDataLink desendants), probably because TBindLinkDataLink is control-agnostic.
To overcome this, traditional DB-aware architecture comes to rescue : simply create a TFieldDataLink that will hold the link between LiveBinded DataSource and the UI control, like

  with TFieldDataLink.Create do
  	Control := aEdit;
  	FieldName := 'aField';
  	DataSource := BindSourceDB1.DataSource;

Want more details through a live example, download [this].

> Monitoring SQLite® database
With RAD Studio XE3®, Embarcadero added native SQLite database driver within their dbExpress framework. XE3 feature matrix says : "New in XE3! TSQLMonitor support for SQLite".
This requires some tweaks (via the Object Inspector) in the current TSQLConnection : under SQLiteConnection.Driver property, add a DBXTrace Delegate Driver.

Want more details through a live example, download [this]

> Generic classes: through another example of composition, typecasting avoiding
Each time there's a novelty in the language, I'm wondering how this is going to be useful in my current /coming projects.
With Generics (or parametrized types), one obvious with it is that it flattens class hierarchies: instead of 2 levels and multiples classes, you can get the same done with only one *generic* class.
But another clean-code plus is that you can avoid typecasting.

How ? .. look at the example [here]

> Anonymous Method use case
Delphi 2009 came with some novelties among them 'Anonymous Method' (AM). Reading litterature about it made me think "nice .. but what for specific use may I need it ?" or in other words "what stuff cannot be made without it (AM) easily or nicely ?".
After searching and searching again, I found a situation where AM makes a more concise /readable code : when you want that a procedure variable be declared in the local context (not in the application scope).

For more details, download the demo [here]

> Sometimes you need make communicate 2 applications on the same PC *without the hassle of a middleware layer*.
It's very easy : on the Sender application, send the message with [Winapi.Windows.SendMessage] procedure; on the Receiver application, create a procedure that will capture the message; the link between both application procedures will be the message Id (integer).

Download a simple demo [here]

> How about using records instead of objects
since Delphi7, records are more alike objects (read this). But the advantage of using records instead of objects is that you don't need to create them. And , of course, if you don't have to create them, you won't need to free them.
For frequently used entities, this leads to increasing run-time performance, with gaining in readability.
Let's look at an example:

1. declaring a record:

   TFieldListRecord = record
     FItems: array of TFieldRec;
     function GetCount: integer; inline;
     procedure Load(const aJvCsvTableName: TFileName; const KeyFields: string; KeyValues: Variant);
     function IndexOf(const s: string): integer;
     property Count: integer read GetCount;
     procedure SetItem(const FieldName: string; const FieldValue: Variant);
     function GetItem(const FieldName: string): Variant;
    function TransformToXML(const RootTag: string): string;

2. using this record:

   FL: TFieldListRecord;
   FL.Load(aFile, 'id', 10); //no need a Constructor
   Edit1.Text  := FL.GetItem('name');

> How to add fields to a TDataSet at run-time

  with TStringField.Create(aDataSet) do // create a TStringField, but can be any other field.
  	FieldName := 'aFieldName';
  	FieldKind := fkLookup;
  	DataSet := aDataSet;
  	Name := DataSet.Name + FieldName;
  	KeyFields := 'aKeyFields';
  	LookupDataSet := 'aLookupDataSet';
  	LookupKeyFields := 'aLookupKeyField';
  	LookupResultField := 'aLookupResultField';
aDataSet.FieldDefs.Add(FieldName, TStringField, 25, False); end;

> WebSnap™ simple project
Have you ever heard of WebSnap™ technology being deprecated by CodeGear /Embarcadero®?
I hope they won't do that, because WebSnap™ is a really nice technology to work with if you have any web development to do with Delphi.
Here is a simple project /tutorial that shows some things that are neither hard to understand nor to implement, and that you simply cannot do with WebBroker framework.

[here] the source code of the project.

> How to get selected a text drawn on a TCustomControl descendant, depending on mouse click:

[here] the source code of the example and the component.

> How to buid an intranet search engine using MS index server and ADO DB connection

Main steps will be to:

  1. add to MS index server configuration pane the catalogs you want to scan. [click here for more details].
  2. check that both IIS and MS index server are running. [click here for more details]
  3. develop a simple Delphi CGI application that will use ADO DB connection for accessing to MS index server database.

> How to check memory leaks on a CGI web application (use Delphi5 professional)
NB: with higher versions of Delphi, use FastMem memory checker and the IDE web app debugger

[back to top]


> Le Mot le Plus Long (v 1.01) , d'après le célèbre jeu télévisé ..

  • Programme exécutable (sans le dictionnaire)
  • [cliquez ici] (262 Ko)
  • Sources Delphi (sans le dictionnaire):
  • [cliquez ici] (23 Ko)
  • Dictionnaire français (en format texte)
  • [cliquez ici] (638 Ko)

    > Le Compte est Bon, d'après le célèbre jeu télévisé ..

  • Programme exécutable
  • [cliquez ici] (171 Ko)
  • Sources Delphi
  • [cliquez ici] (3 Ko)

    [back to top]



    Learn Delphi

    Learning resources

    Delphi About

    my favourite ..

    Delphi - Club d'entraide des développeurs francophones

    web site in french

    CodeRage downloads

    code source


    Embarcadero - RAD in Action


    CodeRage8 replays videos  
    Embarcadero on Youtube videos  
    Embarcadero Academy videos  

    The Delphi Magazine


    > Libraries & Components

    GetIt packages general

    Github Awesome Pascal


    Delphi Super Page


    Torry's Delphi Pages


    Project Jedi






    > Newsgroups & Forums

    Stackoverflow for Delphi

    general programming forum

    Delphi Praxis

    Delphi forum

    Search CodeGear* Newsgroup Database

    newsgroup search engine


    newsgroup search engine


    Google groups

    newsgroup search engine

    Delphi Newsgroups

    newsgroup via http

    Delphi Newsgroups

    newsgroup via news protocol

    Unofficial RAD Studio documentation



    > Application library

    Delphi and C++Builder Application Showcase showcase  
    Good Quality Applications Built With Delphi listing

    > Embarcadero

    Delphi main page presentation
    Customers Portal Licenses
    Embarcadero Resource Center resources

    Embarcadero Developer Network (EDN) for Delphi


    Embarcadero Community


    Embarcadero Events events

    EDN - CodeCentral


    EDN - QualityCentral

    report bug

    RAD Studio Quality Portal

    report bug

    RAD Studio documentation documentation
    Online Help for Delphi 10 Seattle documentation
    RAD Studio Code Examples examples
    RAD Studio Demo Code demos

    Cary Jensen Editor Key Combination Table



    RSS feed


    > Books

    listing#1 books
    listing#2 books
    listing#3 books
    listing#4 books
    listing#5 books
    listing#6 books
    Idera listing books
    Packt listing books

    [back to top]

    Powered by Delphi
    Updated on November 20th 2023 Delphi programming