Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

A Quick Look at Borland's Delphi 95


A Quick Look at Borland's Delphi 95

Mark is a senior consultant with Sema-phore. He can be reached on CompuServe at 76605,2346 or at [email protected].

At first glance, Borland's yet-to-be-released Windows development tool code named "Delphi 95" is similar to Visual Basic. The main interface is located in a single window at the top of the screen, and there is a form, edit window, and property/event inspector. Quickly, though, some differences become apparent. Unlike VB, the main window also contains the component palette from which you pick controls to use on your forms. Borland has made good use of tabbed dialogs to pack a lot of information into a little space. The component palette, for example, has eight pages containing various categories of controls. All told, there are 68 Delphi and VBX controls included with the version I received, with everything from Windows standards to drop-in media players and data-aware grids. Also, the interface is exactly what you'd expect if VB's interface had been merged with that of an IDE for a full-blown compiled language, with all its associated tools. The result definitely has that Borland IDE feel.

The environment is complete and well-organized. The editor window uses tabbed notebook pages to hold multiple files, and multiple editor windows can be open. Syntax highlighting is available, and there are key bindings for Brief, Epsilon, and "IDE classic" along with the default settings. An incremental search feature lets you search for text by typing, and is a nice addition. There is also a full-featured integrated debugger, a browser, alignment and sizing tools for controls, and a customizable "transfer menu" for accessing outside tools. By default, this gives access to a still-quirky bitmap editor and Turbo Debugger, which is useful for "hard-mode" debugging of message-response functions and the like. The browser seems capable, but it is not well documented in this release, and I didn't spend much time in it beyond some initial exploration of the Delphi class library. Just about everything in the environment--contents of control palettes, speedbars, and so on--is customizable via options settings.

An Object Inspector obtains information about the properties and events supported by a control by querying information about the control's class. Borland calls these classes "AppBuilder Objects," and they are based on an object model that has been extended from the one in Borland Pascal. AppBuilder classes are declared using the class keyword, and all derive from a base class

TObject, which introduces common methods. The new classes are compatible in some ways with objects from BP 7.0 and earlier, and both can be used in the same program. Among the extensions to the syntax are the concepts of "Properties" and "Events," and the new access directives, "protected" and "published." Protected attributes, properties, and methods are available to derived classes. Published properties are available at design time, and public properties, at run time.

It is important to distinguish between attributes and properties. Both may be public, protected, or private, but generally only properties are published. Attributes represent what we normally think of as "member data" of a class. Properties are a special class of attributes which may be accessed at run time, and are usually available at design time. A typical property might be the background color of a TMemo control, though they are by no means limited to visual aspects of controls. Properties are declared using a special syntax which binds them to read and write access methods. An access method may take the form of a member function or a direct access of an attribute. In either case the implementation (function or attribute) is intended to be private, and accessed through the property. Providing only a read method makes the property read-only. Since access may be through a function, side effects are possible. Setting the memo-control color property at run time, for example, causes the control to repaint in the new color.

Events are a type of property. From the perspective of the control user (the programmer) an event is a name (such as OnClick for a button) which can be associated with a handler in a form object (or other object instance) using the Object Inspector. If you're creating a control, events are method pointers, a new procedural type. These special method pointers are 8-byte types which define a pointer to a procedure with a certain signature, and also point to the instance on which to call the procedure. For example, TNotifyEvent represents a pointer to a procedure that takes no parameters. A property of type TNotifyEvent could hold a pointer to the handler for the OnClick event. OnClick is a "standard" event, a class of events defined in class TControl, and inherited with a protected access level. To make inherited standard events visible in a derived control, the properties are redeclared as public or published. Only published events are available at design time. When a property is redeclared in a derived class without specifying an access method, the protection level is simply changed.

Because events are properties, they are bound to read and write methods like any other property. Unlike other properties, the access must be through an attribute, not a procedure. By convention the access methods for an event take the event name prepended with an "F". So a handler for an OnClick event would be declared in TControl as FOnClick. Event properties are the "high-level" event-handling mechanism. Controls initially receive events through a lower-level mechanism using message-handling procedures to pre- or postprocess events. These procedures, which are inherited and may be virtual, then access the event property, invoking the user-defined handler procedure on a specific instance through the method pointer attribute. If a control overrides a message-handling procedure, it must invoke the inherited version explicitly. In addition to the standard events, a control writer can define custom events specific to the needs of the control, but that subject is an article in itself. Unless you're creating a new control, something you can do from within AppBuilder, you won't need to worry about declaring properties or events, and will be using prebuilt controls, derived versions of the form classes, and noncontrol classes representing domain concepts.

The event model in Delphi does a good job of hiding the Windows messaging pipe from users and creators of controls. However, one of the important attributes of Delphi is that you are free to work at whatever level of abstraction you like, and if that means you want to access the Handle property of a windowed control and use Send Message to tickle it, you're free to do so. In my experiments, the standard components maintained internal consistency when I used a message to alter a property. For example, the TMemo control SelStart and SelLength properties determine the selected text in the control, and this text is available through SelText. Using an EM_SETSEL message sent directly to the control's window caused the values of the properties to change accordingly. This kind of consistency is important where you are allowed full access to the Windows API.

Another useful addition to the language is run-time type information (RTTI). RTTI is used to inform an application (such as the Object Inspector in AppBuilder) about the class of an object, which in turn provides information about its properties and events. The class name and any properties contained in a published part of the type declaration are made available via RTTI. Applications can use the is keyword at run time to determine if an object is of a particular class. RTTI also enables additional syntax for safe typecasting using the as keyword. This keyword performs a type-safe cast, which is equivalent to the familiar parenthesized form, except that it raises the EInvalidCast exception if the cast is type incompatible.

Delphi ships with a large class library. In addition to its many visual controls, there are a number of nonvisual controls, dialog controls, and noncontrol classes. Dialog controls include common dialog boxes, which are represented by control icons at design time, but are invisible at run time. Adding a common dialog to your app is as simple as placing the control somewhere on the form where you can get to it, setting whatever initial properties are available, defining event handlers if required (such as for the FindNext event from the Find dialog), and then calling the component's Execute method at run time. You can also create your own custom dialogs as forms. Delphi includes several dialog form templates. Delphi definitely encourages the blurring of the line between dialogs and windows. The common dialogs are either modal or not, depending on their nature. Custom dialogs, though, are simply another kind of form. Any form can be displayed modelessly using the Show method, or modally using the ShowModal method. Once you've defined a custom form, you can export it to a DLL, complete with its AppBuilder controls, for use by another Windows app. This means that a C++ program, for example, could use Delphi forms to implement its interface.

It is easy to customize the control palette in Delphi by adding your own controls, or those purchased from third parties. For the immediate future, purchased controls will most likely be VBX's, but it would not be surprising to see a market for Delphi controls arise. VBX's are supported by generating an Object Pascal wrapper. This extra layer of indirection certainly adds some overhead, but given that controls are event generators, it is difficult to see where a little extra time spent crossing the control/ application-call boundary is going to be significant. Controls such as timers might suffer to some extent, but this type of control is already available in native Delphi format. Both kinds of controls are added to the control palette from the AppBuilder interface. After selecting the controls to add from a dialog, the environment automatically rebuilds the component library where they are stored. On my system, this process took about 30 seconds. Like VBXs, the Delphi control format includes property information for the editor, an icon for the toolbar, and, potentially, help information.

Once you've placed a few controls, defined a dialog form or two, written the supporting logic, and edited properties and event handlers, you hit the run button and remember what you liked about Turbo Pascal: The blazing compilation speed. The only real advantage of VB's interpreted language tumbles to the dust as Delphi blasts through the source. I wrote a sample app of about 550 lines of code with a dozen or so procedures and about that many controls. A full build on my 486/33 required about five seconds. According to Borland there are no real improvements in the speed of the BP 7.0 compiler, but since much of the code is in precompiled units, it seems a lot faster. The executable topped out at 230 Kbytes without debugging information (almost 500 Kbytes with) but was pretty snappy on startup, requiring less than five seconds to be active and ready to load a file, or a bit more if a file name is passed in on the command line. I did no serious performance tests, but can say that the application does not seem slow.

The version I reviewed included IDAPI and ODBC database interfaces, and drivers for various DBMSs including Sybase, Oracle, dBase, and Paradox. A local Interbase server was missing but will be included for release. These features, along with the database controls, will probably appear in a client/server version of the product aimed at users of Powerbuilder and other 4GLs. Borland will also ship a desktop version without the database stuff. Both should ship in the first quarter of 1995. The current compiler generates 16-bit code, but Borland has a 32-bit compiler in the warm-up pen, which should go to beta shortly before Windows 95 ships and be released soon after the operating system. That version plans support for Win32, OCX controls, and 16-bit VBXs in a 32-bit environment. Also planned is the ability to export AppBuilder controls to a DLL for use by other applications, something that can only be done with complete forms in the 16-bit version. Borland claims that existing 16-bit Delphi apps will be a straight recompile into Win32.

The Delphi language and development paradigm combines the best of what Visual Basic and compiled object-oriented languages have to offer. Bear in mind that some of this information will change by the time the toolset hits the market. Still, the ease of moving from higher to lower levels of abstraction as need dictates, the ability to develop custom components right in the environment, support for VBXs, the very large and rich set of available controls, and the enhancements to the Object Pascal language, all combine to create an obvious winner. Borland is positioning Delphi as a client/server product and says that it isn't targeted directly at Visual Basic users. But Delphi is very much a general-purpose Windows programming environment. It is a complete Pascal implementation (it will compile BP 7.0 source) and is so flexible that it can be used to develop nearly any type of application. If it isn't targeted at VB, then the shot is going to land pretty close anyway. VB programmers with the ability to move up to Pascal are going to like Delphi. The tool will probably attract many C++ users as well. What little Delphi lacks in terms of C++'s power, portability, and broad industry base, it makes up in sheer productivity and flexibility. Where these attributes matter, it will be a very attractive choice.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.