Just a few months ago, Bob Cringely's InfoWorld gossip column carried a piece to the effect that Microsoft had been using Borland Delphi to put together a new visual tour guide. This raised more than a few eyebrows, particularly because the tour guide was intended to form part of Microsoft's latest incarnation of the Visual C++ (VC++) development system. As a rule, development-system vendors are not noted for building their software with other vendors' products.
So what exactly is Delphi? And what makes it so attractive that--allegedly--even Microsoft's programmers want to use it? In essence, it's a child of the union between Borland's stunningly fast object-oriented Pascal compiler and a Visual Basic (VB)-style front end.
There are similarities between VB and Delphi. Components of both have properties that enable you to control their appearance and behavior. For example, double-clicking on a component at design time immediately puts you in a code-editor window (see Screen 1), where you can enter the code for a new event handler (a small piece of code that responds to an event such as a key press or a mouse click). Both follow a Rapid Application Development (RAD) paradigm when building a user interface. With this approach, you lay out one or more controls--components in Delphi-speak--on a form and then link them together by writing event handlers. But there, the similarities end.
The Design Environment
In VB, the Toolbox grows larger as you add more controls to the system. In Delphi, the Component Palette (the Delphi equivalent of the VB Toolbox) is split into tabbed pages that enable you to neatly divide a large number of components into different functional groups. For example, the upcoming 32-bit version of Delphi has a palette page called Win95, which contains all the new Windows 95 controls. Thus, the Component Palette remains relatively compact even if you install a number of controls.
The Object Inspector is the Delphi equivalent of VB's Properties window. If you use the same "paged" approach as the Component Palette does, you can instantly flip between a component's properties and its event handlers. The Object Inspector also supports nested properties: For example, the Font property is further subdivided into subproperties, such as Color, Height, Style, and so forth. The Style subproperty is nested into fsBold, fsItalic, and more. While VB gives you a "flat" property layout, a single component in Delphi can potentially have a property hierarchy.
Laying out components on a form is easier in Delphi, too. Size and Align dialogs can be used to precisely align components or to force a group of components to be one size.
For user-interface design, Delphi includes container components. A container is a component you can put other components--and other containers--in. This may sound like an odd thing to do, but imagine you want to put a panel with a list box and several push buttons in a dialog box. When you drag the "parent" panel around, the "child" components move with it. Effectively, containers let you build forms within forms. Delphi has several different types of containers, including Panels, GroupBoxes, NoteBooks, and Tabbed NoteBooks.
Another interesting feature of the Delphi design environment is the synergy between the Form Designer and its associated code window. Every time you place a component onto a form, you see the equivalent object-oriented component's definition appear in the code window. Similarly, changes made in the code window are immediately reflected in the Form Designer. Borland calls this approach Two-Way Tools.
In addition, there's the compilation speed: I've yet to see a C++ compiler that I can describe as "speedy." In contrast, Borland's Pascal compilers have always moved quickly, partly because they forgo the industry-standard object file format. Instead, they use a proprietary system that enables the compiler to store a snapshot of its symbol-table information inside each object file. You can compile a moderate-size Delphi application in just a few seconds. Borland claims a compilation speed of around 350,000 lines per minute for a 90-MHz Pentium. The benefits in programmer productivity alone are significant.
Delphi for Database
Despite being at heart a general-purpose development tool, Delphi is geared toward database connectivity. In the entry-level version, its emphasis is on local database support. It includes a copy of the Borland Database Engine (BDE), which can be used to access Paradox, dBASE, and InterBase files or to route via Open Database Connectivity (ODBC). Applications built with the entry-level system can be scaled up to the full client/server version to provide Borland SQL Links drivers to connect to Sybase, Oracle, Microsoft SQL Server, Informix, and others.
The client/server version of Delphi also includes Visual Query Builder to create SQL queries interactively, and a client/server version of Borland's ReportSmith, a report writer. Early developers of BDE applications had trouble figuring out how to set BDE up on a target machine as part of a software installation. However, commercial installation programs that fully support BDE (e.g., Eschalon Setup Pro) are beginning to appear.
To create a database from scratch, you'd typically use the Database Desktop application to specify the database type, the record layouts, and any aliases. This enables your application to refer to the database with logical names instead of physical locations and filenames.
Delphi contains two pages on the Component Palette which are related to database work: the Data Controls page, which contains a rich set of data-aware controls such as DataSource, and the Data Access page, which contains a set of controls used to provide database access such as Table.
With one or more data-aware controls on a form, you'd typically point the DataSource property of each control at a single DataSource component. The DataSet property of the component points at a Tablecomponent.TheTablecomponent refers to a specific database--DatabaseNameproperty--and a specific table within that database--TableName property.
This may sound complicated, but it's a lot easier to use than it is to describe. Why are all the data-aware controls vectored through an intermediate DataSource component? By changing its DataSet property, all the dependent controls automatically refer to a different database or table. This indirection scheme saves you from having to change many individual properties in each control. (See Screen 2 for an illustration of how this works.)