Delphi 3 Activex: A Handy Introduction
Delphi 3 Activex: A Handy Introduction
Delphi 3 Activex: A Handy Introduction
Delphi 3 ActiveX
A Handy Introduction
ON THE COVER
5 Delphi 3 ActiveX Dan Miser
Just in case you don’t know, Delphi 3 is a major player in ActiveX devel-
opment. Mr Miser demonstrates many of Delphi 3’s capabilities in this
area, including: importing ActiveX controls, converting VCL controls into 27 On the Net
ActiveX controls, creating custom ActiveX controls, and more. Picture This on the Web Keith Wood
Mr Wood generates a CGI program with Delphi 3, using its new Web
module components to create a CGI program that delivers pictures
FEATURES from a database to a Web page.
11 Informant Spotlight
ActiveX Scripting Tom Stickle
With ActiveX scripting, developers finally have a platform for adding
standard scripting support to their applications. Mr Stickle shows us how REVIEWS
to employ the tool from Delphi 3. 33 Abbrevia and LockBox
Product Review by Alan Moore, Ph.D.
18 DBNavigator
Insightful Delphi Cary Jensen, Ph.D. 39 High Performance Delphi 3 Programming
So you think you know the Delphi Code Editor? Odds are you’ll be Book Review by Warren Rachele
pleasantly surprised by an item or two uncovered by Dr Jensen in this
in-depth examination of Delphi 3 Code Insight.
23 OP Tech DEPARTMENTS
What’s in the Package? Adam Chace
Its implementation of packages is another important aspect of Delphi 3. 2 Delphi Tools
Mr Chace describes them, puts them in perspective, and spotlights the 4 Newsline
development possibilities. 41 File | New by Alan Moore, Ph.D.
1 February 1998 Delphi Informant
SureHand Software Offers ViCiouS Pro
Delphi SureHand Software intro-
T O O L S duced ViCiouS Pro, a ver-
sion control system that
New Products enables recognition, cus-
and Solutions tomization, and creation of
logical file families. ViCiouS
Pro includes file family defi-
nitions for C++Builder,
Delphi projects, Delphi
forms, Paradox tables, and
dBASE tables.
Users have control over def-
initions for keyword expan-
sion on a per-file extension
basis, with the ability to
establish standard history
blocks for logging com-
ments. ViCiouS Pro also
supports keyword expansion
within incoming and outgo- directly with Delphi and ViCiouS Pro is available in
Blinkinc Ships Shrinker 3.2 ing files. C++Builder. Programmers 16- and 32-bit versions.
Blinkinc announced the ViCiouS Pro supports single- may also access the version
release of Shrinker 3.2, a utility or multiple-user environments. control features by using the SureHand Software
that compresses and transpar-
ently decompresses Windows One copy of common units Archive Explorer. The Admin Price: US$76 per user license, with
and real-mode DOS programs. and forms may be shared Tool provides facilities for discounts for multiple users.
Shrinker 3.2 compresses 16-
and 32-bit Windows programs between multiple projects. defining users, file families, Phone: (314) 963-1935
and resources, including EXEs, ViCiouS Pro integrates and keyword definitions. Web Site: http://www.surehand.com
DLLs, DPLs, OCXs, and ActiveX
controls. This version includes
support for long filenames and
Business Solutions Introduces Client/Server Version of Purchase Manager
an enhanced Windows user inter- Business Solutions, Inc. Complete Delphi source ture allows conversion to
face. Shrinker 3.2 supports
Windows 3.1, Windows 95,
announced Purchase code, implementation assis- any BDE-supported data-
Windows 98, and Windows NT Manager 2.0, a client/serv- tance, and consulting are base.
3.51 and 4.0. er version of the company’s also available. The source
Any EXE, DLL, DPL, or OCX
compressed with Shrinker will purchasing management code version includes the Business Solutions, Inc.
transparently decompress itself system. Written in Delphi, BSI Guardian Application Price: US$10,000, plus US$500
into memory at run time. By
reducing the amount of data it runs against the Oracle Security System, also writ- per user; additional US$10,000 for
transmitted, and decompressing database, and serves medi- ten in Delphi. Although source code.
the program on the local work- um to large organizations. Purchase Manager is writ- Phone: (218) 384-4210
station at run time, Shrinker
minimizes LAN, WAN, and Purchase Manager handles ten for Oracle, its architec- Web Site: http://www.bsi-net.com
Internet traffic. regular and quick
For pricing and information, call
(804) 784-2087or visit requisitions, pur-
http://www.blinkinc.com. chase orders, con-
tract orders and
releases, RFQ bid-
ding, and shipment
orders for raw
materials, spare
parts, and services.
It also includes a
comprehensive
inventory manage-
ment system, and
easily interfaces
with existing
accounts payable
and financial sys-
tems.
Skyline Tools
Price: US$599
Phone: (818) 766-3900
Web Site: http://www.imagelib.com
By Dan Miser
Delphi 3 ActiveX
A Handy Introduction
Figure 2: The RealAudio ActiveX control in action. Figure 3: The ActiveX Control Wizard.
Select Component | Import ActiveX Control, and modify the Not all VCL controls can become ActiveX controls; to display
dialog box to look like that shown in Figure 1. If you were a VCL control in the ActiveX Control Wizard, three require-
to click the Create Unit button, Delphi would generate a ments must be met:
VCL wrapper by reading the type information of the The VCL control must descend from TWinControl. This
ActiveX control, and translating it into Object Pascal syn- may force you to alter the parentage of your VCL control,
tax. The source code would then be saved in the directory but there is usually a suitable alternative. For example, if
you specified for Unit dir name. you’re trying to port a non-visual control to an ActiveX
control, you might consider using TCustomControl as the
However, because all Delphi 3 components need to be ancestor, and provide a simple Paint method.
installed to a package before you can use them in the The VCL control must descend from a control capable of
Delphi IDE, you should click the Install button. This will supporting ActiveX conversion. Most Delphi components
create the unit as previously described, then allow you to use the RegisterComponents procedure to install themselves
insert the component into a package by using Delphi’s stan- to the Component palette. However, if you don’t want a
dard component-installation dialog box. Next, you’ll be control to be converted to ActiveX, you can use the
prompted to rebuild the modified package. After recompil- RegisterNonActiveX procedure to install the component. A
ing, you can treat the ActiveX control as you would any common reason to disallow ActiveX conversion is that the
native VCL component. VCL control references other components. Having
ActiveX controls talk to each other in this manner would
You may have noticed the Add and Remove buttons on this be very difficult, so it’s easier to disallow the conversion
dialog box. These give you a quick, easy way to install and altogether. Delphi’s data-aware controls are a prime exam-
remove ActiveX controls without resorting to Regsvr32, or ple of this. Also, registering a control with
some other registration utility. Figure 2 shows a RealAudio RegisterNonActiveX will disqualify that control’s descen-
component on a form; its Source property is set to a dent components.
RealAudio file, and Play is selected from the context menu. The VCL control must be installed in Delphi. If the com-
Notice that the file is being played at design time. ponent isn’t installed in the Component palette, it’s not
registered with Delphi.
Creating ActiveX Controls from VCL Controls
You may be wondering how to create your own ActiveX Once you click OK, Delphi will convert the VCL control
control that others may use. Delphi comes to the rescue to an ActiveX control. Because an ActiveX control is based
again by providing the ability to convert VCL controls to on OLE, the VCL control can only translate properties
ActiveX controls. This capability is not restricted to that have a corresponding native OLE data type. In addi-
Borland’s standard VCL controls; you can even convert tion, you can provide an adapter to convert the nonstan-
your custom VCL controls. dard data type into something that OLE can understand.
For example, Delphi comes bundled with adapters, so
Select File | New | ActiveX | ActiveX Control to run the ActiveX OLE can use properties of types TString, TPicture, and
Control Wizard. This will generate a fully functional imple- TFont. If Delphi can’t map a data type to a type that OLE
mentation of the ActiveX control, which you can use from can understand, Delphi will omit that property from the
within your Delphi applications. For now, let’s build a sample generated ActiveX control. You can add properties and
ActiveX control based on Delphi’s Calendar control (which methods to the ActiveX control manually by selecting Edit
appears on the Samples page of the Component palette). | Add To Interface, or editing the type library itself. Or, you
Modify the ActiveX Control Wizard to look like the dialog can use the Type Library editor (by selecting View | Type
box in Figure 3, and click OK. Library) and have Delphi 3 do most of the work.
library CalendarX;
uses
ComServ,
CalendarX_TLB in 'CalendarX_TLB.pas',
CalImpl in 'CalImpl.pas' { CalendarX: CoClass },
CalPage in 'CalPage.pas' { CalendarPage: TPropertyPage };
exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;
{$R *.TLB}
{$R *.RES}
{$E ocx}
begin
end.
Figure 4: The source file for CalendarX. Figure 5: TCalendarPage at design time.
Once the code is generated for the ActiveX control, we can To continue our example project, we’ll give CalendarX the
manipulate it as we would any other Delphi project. For now, ability to edit the date, in a property page. Create a property
we’ll save the control, then compile it by using the Project | page by selecting File | New | ActiveX | Property Page. Press OK
Build All menu item.
to generate skeleton code for a property page. After the form
has been created, modify it to look like the one in Figure 5.
After you’ve compiled the ActiveX control and registered it
with the system, any application that can use ActiveX con- The OK, Cancel, and Apply buttons are all provided for you.
trols for development can now access this control. Just for In addition, the tabbed notebook reflects the number of
fun, you can import your resulting ActiveX control into property pages you’ve created. The only controls you need to
Delphi using the steps previously covered. This will allow place on a property-page form are those that implement the
you to view this control as other users might. desired behavior of the property page.
Anatomy of an ActiveX Control The following steps are necessary to completely implement a
Every project created in Delphi needs a project source file property page:
(a .DPR file). ActiveX controls are no exception. An 1) Update the visual controls of the property page to match
ActiveX Library is the project source file for all ActiveX the state of the ActiveX control.
projects. This file exports the four signature methods of an 2) Modify the visual controls.
ActiveX control, provides an extension compiler directive, 3) If necessary, update the ActiveX control’s properties to
and includes the appropriate type library. reflect the changes made in the property page. This is
done only if the OK or Apply button is pressed.
The source file for an example calendar project, CalendarX, is
shown in Figure 4. The compiler directive: Delphi supplies all the pieces to easily implement this logic.
The UpdatePropertyPage method will be called whenever the
{$E ocx}
property page is about to be displayed. This is where you set
the visual controls to show the ActiveX control’s properties.
tells Delphi what extension to give to the compiled version of
For example, the following method will set the edit controls
the project. To create a new ActiveX Library project from
to the values of the ActiveX control:
scratch, you would select File | New | ActiveX | ActiveX Library.
procedure TCalendarPage.UpdatePropertyPage;
The CalendarX control is good, but it would be nice to offer begin
an easier way to edit the properties. This is precisely what edMonth.Text := OleObject.Month;
edDay.Text := OleObject.Day;
property pages were made for. edYear.Text := OleObject.Year;
end;
Property Pages
Property pages give users a friendly way to alter the prop- The TPropertyPage object contains a reference to the ActiveX
erties of an ActiveX control. A property page has a visual control, and places it in a variable called OleObject. Access
control that represents a corresponding ActiveX property. this variable whenever you need to access properties or meth-
These controls are displayed in a tabbed notebook. ods of the ActiveX control.
7 February 1998 Delphi Informant
On the Cover
The ActiveX control must be informed when its properties
change. Whenever a user changes a property via a property
page, you need to call the Modified method of the property
page. This tells the ActiveX control that it needs to update
itself. For example, the following method is assigned to each
Edit component’s OnChange event:
Register the Page Figure 6: A standard ActiveX property page at run time.
The last step is to bind the property page to the ActiveX con-
trol by registering it. This is accomplished by calling the control from scratch. Here’s where studying Delphi’s gener-
DefinePropertyPages procedure inside the ActiveX control’s ated code really pays off.
DefinePropertyPage method. This method was created in the
skeleton code when you created the ActiveX control. Simply pass TreeView components are not listed in the ActiveX
the CLSID of the page that you want to register. You can find Control Wizard mainly because the Items property is of
this value in the interface portion of the property-page unit: type TTreeNodes. This is not an OLE-compatible type, so
procedure TCalendarX.DefinePropertyPages(
there is no automatic way for Delphi to make this struc-
DefinePropertyPage: TDefinePropertyPage); ture ActiveX-compliant. However, with a little reengineer-
begin ing, we can expose some of the functionality of the Items
DefinePropertyPage(Class_CalendarXPage);
DefinePropertyPage(Class_DFontPropPage);
property, thus allowing the control to be manipulated as an
end; ActiveX control.
Note also that you’ll need to add the name of the property- To create this ActiveX control, first make sure all the files are
page unit to the Calendar ActiveX unit (that’s where you closed inside Delphi. Then:
defined Class_CalendarXPage). 1) Select File | New | ActiveX Library to get the project file
used by ActiveX controls. This creates the project frame-
Every property page you define creates another tab on the work for an ActiveX control.
property-page editor. This lets the user concentrate on one 2) Select File | New | Automation Object, and give the object
logically related group of data at a time. For example, you a class name of TTreeViewX. This will create a COM-
could create one property page for modifying the fonts object declaration, as well as a type library. Both these
used in a control, and another for modifying graphic ele- files will be modified throughout the rest of this process.
ments. This would require calling the DefinePropertyPage 3) Make the following changes to the source-code statements
method for each PropertyPage you want to register for this in the Automation Object unit: The TTreeViewX class
ActiveX control. must descend from TActiveXControl instead of TAutoObj.
The factory-creation class in the initialization section
You can also easily give your control the ability to modify must read:
properties of type TFont, TColor, TPicture, and TStrings.
TActiveXControlFactory.Create(ComServer, TTreeViewX,
These property pages will scan through your ActiveX control’s TTreeView,
properties at run time, and let the user modify individual Class_TreeView, 1, '', 0)
attributes of these properties. These property pages are imple-
mented in Stdvcl32.dll; therefore, if your control accesses one 4) Add the extension directive to the project source file. This
of the standard property pages (see Figure 6), you’ll need to step ensures that when you compile the project, the
deploy this file as well. resulting binary file will have the standard ActiveX exten-
sion — namely, OCX:
ActiveX from Scratch
We’ve seen the powerful ability of Delphi to generate {$E ocx}
By Tom Stickle
ActiveX Scripting
Adding Scripting to Your Delphi 3 Applications
session. The last step is to call InitNew, then change the { See if anything was found for the EventName --
Spelling Error will fail! }
engine state to connected. We have now successfully fired if disp = -1 then
up the scripting engine. begin
ShowMessage(Format(
'The method %s was not found in the script...',
Parsing the Script [EventName]));
Now that we have a mechanism for starting the engine, we Exit;
must have a way to submit our script for parsing and exe- end;
cution. This is accomplished through the use of the { Set the type of invocation to method. }
IActiveScriptParse interface and its ParseScriptText method. InvKind := DISPATCH_METHOD;
We can conveniently bundle this call into a Delphi
{ This structure can contain up to 32 arguments to pass
method (see Figure 3). in, but we will not pass any in the demo. }
ReturnVal := nil;
Resetting the Engine DispParams.rgvarg := nil;
DispParams.rgdispidNamedArgs := nil;
In many cases, you’ll probably want the ability to submit a DispParams.cArgs := 0;
script, execute it, but then reset the engine so you can repeat DispParams.cNamedArgs := 0;
the process with another script. This can be done by chang-
{ Fire the Event via ID Binding. }
ing the script state from connected to uninitialized. The ScriptDispatch.Invoke(Disp, GUID_NULL, 0, InvKind,
Delphi method shown in Figure 4 accomplishes this. DispParams, ReturnVal, @ei, nil);
end;
Firing a Script Subroutine Figure 5: ID binding allows for generic code to call a routine
Fortunately, the scripting engine gives us the ability to selec- in script.
tively fire individual subroutines or functions in the script
from our Delphi application. This is possible because the
scripting engine exposes all subroutines through an automa- We simply query the IDispatch interface for the DispID that
tion interface at the time the script is parsed. We can now corresponds to the name of a script routine, and then invoke
treat the methods in the script as if they were methods in any that method based on the DispID. This technique is known
standard dual automation object. as ID binding, and enables us to create generic code for call-
ing a routine in the script (see Figure 5).
A dual automation object is essentially an ordinary COM
object. As with any COM object, it has a vtable that con- Exposing Application Objects to the Script
tains pointers to its methods and properties. The big dif- For the scripting engine to have true significance to an
ference is that it also contains a dispatch interface — or application, we must be able to expose an application’s
dispinterface — that assigns a unique integer identifier, Automation objects to the script, so that users can easily
referred to as a dispatch identifier (DispID), to each access them without knowledge of COM. After all, one of
method and property. The second major difference is that the major advantages a scripting language provides is that
a dual automation object inherits from an interface, called users can control the logic of complex tasks without having
IDispatch, which provides a method for calling any other to know all the details. For example, a script writer may add
methods in the vtable based on its DispID. the following code to a script:
if CountDown = 0 then
The clear advantage of this mechanism is that we now have Rocket.Launch
the ability to execute any routine in the script at run time. end if
You can implement ShowCelcius as shown in Figure 6. This is The files referenced in this article are available on the Delphi
a simple routine that converts Fahrenheit temperatures to Informant Works CD located in INFORM\98\FEB\DI9802TS.
Celcius. Be sure to add Dialogs and Demo_TLB to the uses
statement, register the type library using the Type Library edi-
tor, and then register the new object with the OS.
We need to make two modifications to make our new object Tom Stickle lives in Phoenix, AZ. He can be reached at (602) 598-1890, or via
available to scripting applications. When you initialize the e-mail at [email protected].
scripting engine, you can add the name of your object to the
14 February 1998 Delphi Informant
Informant Spotlight
Result := S_OK;
End Listing One end;
function TActiveScriptSite.GetDocVersionString(
Begin Listing Two — SCRIPTSITE.PAS var VersionString: TBSTR): HResult;
{ This implements the required begin
IActiveScriptSite Interface. } { Tell engine that we will accept its default,
unit ScriptSite; i.e. not implemented. }
Result := E_NOTIMPL;
interface end;
uses
Windows, SysUtils, comobj, activeX, Activscp, Dialogs, function TActiveScriptSite.OnScriptTerminate(
Forms, ComServ, Demo_TLB; var VarResult: OleVariant;
var ExcepInfo: TExcepInfo): HResult;
type begin
{ TActiveScriptSite Declaration. } { This tells us that the script is completed. }
TActiveScriptSite = class(TComObject, IActiveScriptSite, Result := S_OK;
IActiveScriptSiteWindow) end;
protected
{ IActiveScriptSite } function TActiveScriptSite.OnStateChange(
function GetLCID(var wLCID: TLCID): HResult; ScriptState: LongInt): HResult;
virtual; stdcall; begin
function GetDocVersionString(var VersionString: TBSTR): { Alerts us when engine states are changing. }
HResult; virtual; stdcall; Result := S_OK;
function TActiveScriptSite.OnScriptError(
pAse: IActiveScriptError): HResult;
var
wCookie: Word;
ErrString: string;
ExcepInfo: TExcepInfo;
CharNo: LongInt;
LineNo: LongInt;
begin
wCookie := 0;
LineNo := 0;
CharNo := 0;
if Assigned(pAse) then
begin
pAse.GetExceptionInfo(ExcepInfo);
pAse.GetSourcePosition(wCookie, LineNo, CharNo);
pAse := nil;
result := E_FAIL; { Halt script execution! }
end;
function TActiveScriptSite.EnableModeless(
FEnable: WordBool): HResult;
begin
{ Causes the host to enable or disable its main window
as well as any modeless dialog boxes. We won't need
this for our demo. }
Result := S_OK;
end;
initialization
TComObjectFactory.Create(ComServer, TActiveScriptSite,
IID_IActiveScriptSite, 'ActiveScript Host', '',
ciMultiInstance);
end.
Insightful Delphi
Delphi 3’s Code Insight Feature
Figure 2: Code Completion can also display the members Figure 3: Right-click the list displayed by Code Completion to
visible from a class reference. change its sort order.
the TForm1 class includes private declarations, because private dures, and functions that are visible from your unit. For
members are accessible within that unit. However, if the example, imagine you are typing the following into a unit that
TForm1 class is declared in another unit (and that unit is using the Dialogs unit:
appears in an appropriate uses clause for the unit you are edit-
if MessageDlg(
ing), Code Completion will display only the public and pub-
lished members of a TForm1 instance. Protected members are
only displayed when you are editing a method associated with Shortly after typing the open parenthesis, Code Parameters
the class within which they are declared, or a method in a will display the syntax of the parameters of this function, as
class that descends from the one in which they are declared. shown in Figure 4. The parameter you are currently entering
Again, this corresponds to member visibility. is displayed in bold. If there is more than one parameter, the
bold type face in the Code Parameters window advances to
When you install Delphi 3, this list is sorted alphabetically by the next parameter as you complete each one.
default. You can, however, change the sort order by right-
clicking the list and selecting Sort by Scope, as shown in While Code Parameters, like Code Completion, is displayed
Figure 3. You can return to an alphabetically-sorted list by automatically, the Help window will be removed if you move
right-clicking and selecting Sort by Name. your cursor to another line of code. If this happens, you can
re-display the Help window by moving your cursor back to
Once the Code Completion list is displayed, you can have Code the argument list and pressing CSM.
Insight enter one of the listed members at your cursor by first
highlighting the desired member and then pressing J. There Argument Value Lists
are two ways to highlight a member. One way is to search incre- Argument value lists can be generated when you are entering
mentally. Specifically, begin typing the name of the member you an expression, such as the actual parameter in an argument
want. As you type, Code Completion will move through the list, list or the expression on the right side of an assignment state-
highlighting the member whose name most closely matches ment. Unlike Code Completion and Code Parameters, the
what you typed. The second technique is to use your cursor
keys, t, b, h, e, etc. You can use these techniques con-
currently. For example, you can begin by using an incremental
search to move to the general vicinity of a member in the list,
then use the cursor keys to select it. For obvious reasons, incre-
mental searching is usually only effective when the list is sorted
alphabetically.
Code Parameters
The Code Parameters feature of Code Insight provides on- Figure 4: Code Parameters displays the syntax of the argument
the-fly syntax display for the arguments of methods, proce- list for a function, procedure, or method.
Figure 5: Press CM to see the list of expressions valid in the Figure 6: Press CJ in the editor to display defined code
current context. templates.
Argument Value Lists feature must be specifically requested types). To change the sort order of the argument value list,
by pressing CM. The list generated displays the con- right-click the list and select the sort order you want.
stants, functions, and variables that are consistent with the
argument required by the expression. Code Templates
A code template is a pre-defined snippet of code that can be
I think this is the most powerful feature available in Code inserted into the editor at your request. For example, if you
Insight. Unfortunately — and ironically — it is unknown to want to enter an if statement, position your cursor at the
most Delphi developers. In fact, the section of the User’s location where you want the code template to be entered,
Guide that ships with Delphi 3 fails to even mention then press CJ. Code Insight displays a list of the existing
Argument Value Lists. I even attempted to locate some men- code templates, as shown in Figure 6.
tion of it in the online Help while writing this article, but
was unsuccessful. I know it must be in the online Help some- As with the argument value list, you can navigate this list of
where, because that’s how I learned of this feature (shortly code templates by using t, b, h, e, etc., or by con-
before Delphi 3 shipped). However, I am unable to locate a ducting an incremental, alphabetical search of the entries.
reference now. Once the template you want is highlighted, press J to
select it. Code Insight responds by entering the code, and
In any case, it is a Delphi 3 feature, and a powerful one at placing your cursor within it.
that. For example, imagine that while you are entering the
function MessageDlg you cannot recall which values are The code template list that appears when you press CJ
acceptable for the second argument, DlgType, which is of the has two columns. The first column contains the template
type TMsgDlgType. Such a situation is perfect for Argument description; the second column contains a shortcut, or
Value Lists. With your cursor poised to enter the second mnemonic, for the template. The shortcut contains no
argument, press CM. When you do, Code Insight gen- spaces, and must be unique for each template. For example,
erates and displays a list of the symbols that are visible to the shortcut for one of the if templates is ifeb. Once this list
your unit that match the data type of the required expression. of templates is displayed, you can perform an incremental
The list generated for the second argument of the MessageDlg search on the shortcut, use your cursor keys, or both. After
function is shown in Figure 5. you’ve highlighted the entry of the template you want, press
J to have Code Insight enter the template at the position
As with Code Completion, while the argument value list is of your cursor.
displayed you can begin typing the name of the symbol you
want, use your cursor keys to navigate the list, or both. Once If you know the shortcut associated with a particular code
the symbol you want entered at your cursor is highlighted, template, you can access the template directly by typing the
press J to have Code Insight enter the value. shortcut, then pressing CJ. If the characters of the short-
cut you have typed are unique to that shortcut, the code
Also similar to Code Completion, you can sort argument template is entered without the template list being displayed.
value lists alphabetically or by scope. In most cases it’s best to
have this list sorted by scope, because that will place all expres- If two or more shortcuts share the same characters as the one
sions of the matching type as required by the expression at the you entered, a short list of only those templates whose short-
top of the list. This is useful because the list not only includes cut names match what you have entered is displayed. For
symbols that match your expression exactly, but also includes example, if you enter if, then press CJ, the code tem-
any variants that are visible from your unit (because variants plate list contains all templates whose shortcuts begin with
are assignment-compatible with a wide range of expression “if ”, as shown in Figure 7.
Figure 7: If you enter only part of a shortcut name, and that part Figure 9: Tooltip Expression Evaluation permits you to inspect
matches two or more templates, Code Insight displays a short list of the value of variables and properties at run time, without using
the matching template shortcut names from which you can choose. Run | Evaluate/Modify or setting watches.
Notice that the vertical bar ( | ) was placed where one or more
statements must be entered. The vertical bar character defines
where you want the cursor placed after the template has been
entered. If you now enter repeat in the code editor and press
CJ, the entire template will be entered, and your cursor
will appear on the line following the keyword repeat.
Conclusion
Code Insight is a valuable new productivity tool for Delphi 3
developers. It can significantly reduce keystrokes, and the
time you spend in Delphi’s online Help. ∆
By Adam Chace
P ackages offer Delphi developers a new way to deploy applications with run-
time libraries. Forget the hassles of trying to incorporate VCL objects into
standard DLLs; with Delphi 3’s new packages feature, deploying shared
libraries of Delphi units and components is a cinch, and you don’t have to
change a single line of code. This article will provide an overview of what pack-
ages are, and how to use them.
Like standard DLLs, packages are essentially DLL. These libraries are used at design time
just bundles of code that are referenced by a by the IDE, and can then be incorporated
given application, be it an .EXE, an at run time by your application.
ActiveX control, a .DLL, or even another
package. Borland has given packages a The .DPL file isn’t the only file associated
.DPL extension to differentiate them from with a package, however. There’s also the
common DLLs, but their architecture is .DCP file, a single file collection of all the
almost identical to any implicitly linked DCUs your package contains; and the
.DPK file, the editor file that specifies
which .PAS files a particular package con-
tains, and which .DPL files a package
requires. The .DCP file is only of interest if
a package is distributed without source code
or the associated DCUs. In these cases, the
.DCP file is used when you compile your
package. The .DPK file is used any time
you edit a package, as we’ll soon see, and is
modified every time you add or remove
items to or from a package.
Figure 5: Our application compiled without using packages. Figure 7: The same application compiled with run-time
packages.
Once you’ve decided whether you want to remove any files from That’s all there is to it. Run-time packages are an easy way to
this list, click OK, and build the application. It’s important to reduce your deployment costs, and you don’t need to make
25 February 1998 Delphi Informant
OP Tech
Conclusion
As we have seen, packages are an exciting new feature for
Delphi programmers to exploit. While design-time packages
streamline the use of the component library, run-time pack-
ages provide the real power. Delphi programmers can easily
segment and distribute portions of functionality, independent
of the .EXE file. This significantly reduces the amount of
effort involved with distributing application updates. ∆
By Keith Wood
Web Graphics
HTML documents define what appears on Web pages. It
consists of straight text, interspersed with formatting and
metadata commands (tags), which are delimited by angle
brackets (< >). These tags allow the specification of headings
and character and paragraph formatting, as well as define the
links that make the Web what it is.
To access a database, we need several pieces of information: Along with this, the id of the scheme to retrieve (or zero
the BDE alias, the user id, and a password. Furthermore, to when adding) is specified. This action parameter is looked for
access a table and extract an image, we require the names of in the program, which causes it to generate a page containing
the table, its key field, and the BLOB and image type fields. all the details for a single scheme, and allows these to be
altered. The pages come from two TPageProducer compo-
For this exercise, we store all this data in the registry. nents, where each page is set up as an HTML form. The
Under a common key, \Software\Kwood\WebPics, we forms’ actions call the program again, passing back the fields
maintain one key for each database scheme that we wish to for a scheme.
access. Within this key are the individual values for the
data identified above. To hide the password from prying After entering the requested data, the user sends the new
eyes, a coding scheme is used. In this case, it’s a simple details, which now arrive with an action of Add or Update,
30 February 1998 Delphi Informant
On the Net
Now, TurboPower has helped fill that void C++Builder) programmer can now add such
with two of its newest component libraries: support. Exactly what kind of support are we
Abbrevia, which provides support for work- talking about? Let’s see.
ing with PKZip-compatible files; and
LockBox, which supports the encrypting and Abbrevia supports the compressing and
decrypting of files. While the two libraries decompressing of files, adding them to, or
are quite different, there’s at least one situa- deleting them from, an archive, and view-
tion in which I can imagine using the two of ing the contents of an archive — all com-
them together: transmitting sensitive data mon operations. It also provides support
over the Internet. for some of the less common operations,
including creating a self-extracting archive
I’ll begin by discussing each of these libraries (an .EXE file that, when executed, extracts
separately, concentrating on their uses and all the archived files stored within it), and
their special features. Then I’ll examine some even compressing or decompressing on-the-
of the common features in both libraries. fly without saving to a file. Let’s take a
We’ll begin with Abbrevia, then turn our look at the components and classes that
attention to LockBox. make this possible.
All the stream methods are faster than the block methods.
The Triple Data Encryption Standard is by far the slowest
because it uses a 128-bit key and applies the DES encryption
algorithm to the data three times. Generally, block and stream
ciphers are appropriate for different programming situations:
Block ciphers work well with data in memory while stream
ciphers are ideal for operations involving files. I’ll have more
to say about the latter when I discuss the stream support in
LockBox and Abbrevia. The block ciphers are demonstrated
fully in the example program, ExLBox (see Figure 6). You can
use this program to test the relative speed of the various
methods. In addition to its many encryption methods,
LockBox also provides helpful programming choices.
with files in Delphi. They give you the ability to work with a little of the history of data compression, its various methods,
data in memory and copy data structures from one medium and sources of additional information. In LockBox, you learn
to another (e.g. memory to file). Both these libraries take detailed information about the various encryption methods, the
advantage of this, and in doing so increase their value to us. importance of keys, and the uses for stream and block methods.
Again, there’s a list of references if you wish to learn more.
Abbrevia includes two routines (always used together) that
allow you to compress and decompress data without hav- As with TurboPower’s other libraries, Abbrevia and LockBox
ing to hassle with intermediary files. Using DeflateStream, include comprehensive online Help (mirroring the material in
you can save an application’s data files in compressed form the manuals), full source code, and excellent example programs.
when you, or your users, are finished with them, then load This company continues to provide free technical assistance
them again when needed. All this is handled transparently. and a 60-day, money-back guarantee for its products. You can
download a fully functional demonstration version of Abbrevia
Likewise, LockBox provides stream classes, which allow you from TurboPower’s Web site, and find out first hand if it meets
to save encrypted data to a file and later retrieve it using your needs. There’s no demonstration version of LockBox
one of six encryption methods. Figure 7 shows an example because some of its encryption methods are too powerful to be
program, CryptFile, that demonstrates the use of stream exported from the United States.
ciphers. Here again, the encryption is handled automatical-
ly and is completely transparent to the user. From a security Conclusion
point of view, it’s nearly impossible for anyone to make Using native Delphi classes and components, Abbrevia and
sense of the data stored in the encrypted file without first LockBox provide excellent com-
knowing the method used and the encryption key. pression and encryption func-
tionality for Delphi program-
As a bonus, I’ve included a sample program with this article, mers. Once again, TurboPower
ConfiZip, which uses components from Abbrevia and rou- demonstrates its leadership in
Abbrevia is an excellent collection of
tines from LockBox. It first encrypts a text file (using the third-party Delphi market- components and classes that provides a
Abbrevia’s built-in password dialog box) then saves the file in place. That leadership is based complete solution to working with PKZip-
compatible files. Its crowning glory,
compressed format. Naturally, the program also allows you to on meticulous attention to TAbZipOutline, allows you to easily work
with any of the files in an archive (e.g.
reverse this process. Figure 8 shows the layout of the main detail, excellent documentation, browsing, adding, or retrieving). LockBox
form; the code for the main form is given in Listing Three and responsiveness to the needs is a comprehensive collection of encryp-
tion/decryption classes and low-level rou-
(on page 37) and indicates how little programming is and wishes of customers. If you tines for adding data security to an appli-
cation. It includes a large number of
required to take advantage of these component/class libraries. need to add PKZip-compatible options to cover various programming sit-
(You can download all the source code and the 32-bit exe- compression or high-level uations and needs. Both libraries provide
support for Delphi streams, and come
cutable file: see end of article for details). encryption to your applications, with excellent documentation and exam-
ple programs. Abbrevia is available in a
I think you will be more than demonstration version. Both come with a
Other Common Features: Quality We’ve Come to Expect satisfied with these excellent 60-day, money-back guarantee.
try
Memo1.Lines.LoadFromFile(TextFile);
finally
end;
end;
end;
end.
— Warren Rachele
ISBN: 1-57610-179-7
Price: US$49.99
(635 pages, CD-ROM)
Packages
The Potentials and the Pitfalls
T he introduction of packages was one of the major changes in Delphi 3. Before packages, if you wanted
to work with a particular subset of the VCL, your options were somewhat limited. Of course, you could
create and load different versions of complib.dcl. However, this was a hassle, and rather wasteful of disk
space. With packages, those hassles are gone. Unfortunately, they’ve introduced a new set of problems.
But let’s start with the good news.
You Gotta Take the Good … installed on my system. I received the component could also be inadver-
In Delphi 3, if you select Component | following not-so-informative message: A tently installed by someone using a
Install Packages, you see all the packages device attached to the system is not property editor that is dependent
currently installed and the various working properly and the package can- upon it, but written and distributed
options you have: You can add a single not be installed (or something to that by someone else.
package or a collection of packages, effect). Because I knew what I had
remove packages, edit packages, and installed recently, I was able to un-check Leading vendors such as TurboPower
examine the components in a package. one or more packages, getting one to are now aware of the problems that can
If you encounter a problem or conflict work, but not both. arise with packages, and are taking
with a particular package, you can sim- aggressive steps to shield us from them.
ply de-select it by clicking the check Gradually, some sanity has emerged in That particular company, for example,
box. With the Package Editor you can how to work with packages. But this is giving each new product release a
create your own new packages, and with has more to do with the third-party slightly different package name from its
the Package Collection Editor you can developers’ commitment to correcting predecessor to avoid version conflicts. I
create collections of packages to distrib- the problem than with Borland’s lead- greatly appreciate such thoughtfulness.
ute to other developers. ership. Thanks to developers such as However, I can’t help but wonder if all
Ray Konopka, component writers now this could have been avoided in the
Delphi 3 Help points out that “design- have some guidelines to help them beginning if Borland had put as much
time packages ... simplify the tasks of avoid these conflicts. In Developing energy into warning us about the pit-
distributing and installing custom com- Custom Delphi 3 Components [Coriolis falls of packages as they did touting
ponents.” That’s true. When I first Group Books, 1997], Mr Konopka their advantages. What do you think?
installed third-party component imparts some excellent advice to the Let me know your views, experiences,
libraries in Delphi 3, I was amazed at developer who will be distributing problems, and solutions in working
how smoothly the process went. Once components in packages: with packages. ∆
the setup program was finished and I Always use a unique prefix in nam-
fired up Delphi 3, the new components ing your components to avoid con- — Alan C. Moore, Ph.D.
appeared, already installed on the flicts with components created by
palette. What a difference from Delphi other developers. Alan Moore is a Professor of Music at
1 and 2! Make sure your package names are Kentucky State University, specializing in
unique. music composition and music theory. He has
… with the Bad Never put property or component been developing education-related applica-
Unfortunately, I soon encountered editors in run-time packages; these tions with the Borland languages for more
problems: incompatibilities between belong only in design-time pack- than 10 years. He has published a number
packages from some of the third-party ages. of articles in various technical journals.
tool and component producers. These Make certain that the registration Using Delphi, he specializes in writing cus-
conflicts occurred because one product procedures are not in the compo- tom components and implementing multi-
depended upon components in the nent unit (as we’ve become accus- media capabilities in applications, particu-
other, but was using a different version tomed to doing), but in a separate larly sound and music. You can reach Alan
of those components than the one registration unit. Otherwise, your via e-mail at [email protected].
41 February 1998 Delphi Informant