Beruflich Dokumente
Kultur Dokumente
2003
Volume 9 Number 9
INSIDE
ON THE COVER
Greater Delphi
Going Native
FEATURES
.NET Tech
13
Delphi Informant
www.DelphiZine.com
2003 Readers
Choice Awards
Special C# Magazine
Preview Inside!
Use Java
from Delphi
(and Vice Versa)
ASP.NET Apps
Page 18
The Perils of
Weak Encapsulation
Page 28
Open Source
Resources
Page 48
In Development
21
Informant Spotlight
27
REVIEWS
32 ExpressQuantumGrid 4
D E PA R T M E N T S
2 Symposium by Jerry Coffey
3 Toolbox
36 File | New by Alan C. Moore, Ph.D.
S Y M P O S I U M
By Jerry Coffey
Then there are the people here at ICG that make each
months issue of DI a reality. David Riggs started with
Informant within months of when Delphi 1 shipped, and
has been the magazines Managing Editor for most of
the time since. Dave is The Man. Besides being the best
proof reader Ive ever worked with if youre an editor be jealous, be very jealous Dave is the kind of guy
that holds a magazine together, doing the million-and-one
things it takes to produce a monthly publication. And he
makes it look easy.
One half of our mighty ICG Production Department
(with Diana Nishimura whose work graces our asp.netPRO
magazine), Art Dugoni designed the magazine youre holding, and laid in each article as he does every month. And
those awesome covers? Thats all Art.
A first-class Web site is a requirement for a publication such
as DI, and the man responsible for building and maintaining
DelphiZine.com is Bob Silva. If it takes chewing gum and bailing wire at 2AM on a weekend to keep the various systems up
and running here at ICG and sometimes it does! youll
find Bob in the server room, making things work for all of us.
And although he has been here at ICG a relatively short
time, acting CFO Ed Ring, has been instrumental in keeping this publication alive. Were it not for Ed, I wouldnt be
writing this now. Thanks Ed. Thank you also, Debbie Holmgren and Katie Sullivan, who have brought an incredible
professionalism and vigor to Sales. My only complaint: Why
werent you here sooner!
I especially want to thank Mitch and Nancy Koulouris, who
in 1990 had the vision, guts, grit, and wherewithal to launch a
little publication named Paradox Informant. Mitch invited me
to sign on as editor in 1991, so I decided to change careers and
gamble on a start up. Its been a wild ride ever since and weve
never looked back. Paradox Informant was the first of eight
magazines Mitch and I would launch (DI was the third), and
while some did better than others betcha dont remember
dBASE Informant each is now a treasured memory. There
have been plenty of ups and downs to be sure, but I wouldnt
trade the experience for anything.
Finally, I want to thank you the reader. Youre what this
magazine is all about, and youre foremost in our minds as
we put together issue 101.
Thanks for reading.
T O O L B O X
wPDF 2.10 and WPTools 4.11 Available
wpCubed released wPDF 2.10, a
PDF creation engine for Delphi and
C++Builder. This version has been
optimized for greater compatibility
with most drawing commands commonly found in Windows applications.
wPDF 2.10 has everything you need
to create PDF files from ReportBuilder,
RAVE, WPTools, THTMLView, ACEReporter, WPForm, QuickReport, FastReport, and ExpressPrinting System.
Ready to use sample code and filter
interfaces are included.
wPDF converts enhanced metafiles to
PDF while preserving the vector and
text information. This results in small
PDF files which can be printed at high
resolution. wPDF supports the usual
PDF features, including compression
and 128-bit encryption and it was the
first Delphi library to allow embedding
of font subsets to reduce file size.
WPTools 4.11 is
a word processing component
suite that has
been enhanced
to function well
with Unicode
characters and
allow table rows
to span multiple
pages. WPTools
4.11 provides a
word processing
component with
WYSIWYG page layout view, mail
merge, hyperlink handling, and the
full set of possible character and
paragraph attributes. The header and
footer handling and text numbering
in standard or outline mode has been
improved. Optional add-ons, such as
WPReporter or wPDF, make it possi-
T O O L B O X
Embed TAPI ActiveX Objects in Delphi Apps
Internet-aware
SkyDocImage 7 Available
SkyLine Tools Imaging announced
the shipping of SkyDocImage, Internet
Enhanced. This royalty-free document
imaging package comes complete
with full source code for Delphi.
New features include comprehensive
TIFF support; a fast TWAIN manager;
a powerful Expervision TypeReader
Pro or Enterprise OCR gateway; seven
anti-aliasing and scale-to-grey algorithms; zoom, scroll, and pan; a
thumbnail manager; and annotation
capabilities that allow users to mark
up images on screen and save them
either with or without the document.
The package features the original
executable as well as the complete
source code, so SkyDocImage can be
used out of the box as a stand-alone
document imaging solution or it can
be fully customized. With source
code included, developers can use
SkyDocImage as-is or modify features for specific development needs.
This Internet-aware version allows
developers and imaging professionals to easily send, receive, and view
scanned TIFF documents (as well
as other formats) across intranets,
extranets, and the Internet. Programmers who license SkyDocImage can send images to FTP sites
through standard TCP/IP connections. You can even scan directly
via FTP. End-users can receive and
view TIFF images from URLs and
FTP sites using TCP/IP.
SkyLine Tools Imaging
Price: Contact SkyLine Tools for details.
Contact: sales@imagelib.com
Web Site: www.imagelib.com
T O O L B O X
Hurricane Software Releases Hurricane Editor 3
Hurricane Software
announced Hurricane
Editor 3, a syntaxhighlighting editor
that supports more
than 40 file types,
including Delphi,
C/C++, and C#.
Designed to enhance
the productivity of
software developers, it integrates with
other Hurricane Software products.
Hurricane Editor 3
provides fully customizable syntax highlighting to quickly
distinguish elements
such as variables, literals, comments, and
primitives within source code. Syntax
highlighting improves productivity by
providing fast and easy recognition of
source code elements for maintenance
and debugging.
Other features include an integrated
file explorer for rapid point-and-click
access to files and directories; block
indent support to quickly perform
block editing tasks; support for Unix,
Mac, and DOS line ending file types to
accommodate todays heterogeneous
ComponentOne Studio
Enterprise Integrated
with C#Builder for .NET
ComponentOne announced ComponentOne Studio Enterprise for Borland C#Builder. This special edition
of ComponentOne Studio Enterprise
is now integrated with C#Builder
for the Microsoft .NET Framework.
Customers who purchase C#Builder
for the Microsoft .NET Framework
will receive a special integrated
edition of ComponentOne Studio
Enterprise that includes a development and deployment license for all
ComponentOne Studio Enterprise
.NET (WinForms) and ASP.NET
(WebForms) components.
ComponentOne Studio Enterprise
for Borland C#Builder is a
suite of components, including
grid, reporting, charting, data,
user interface, and eCommerce
components for .NET and ASP.NET.
Popular .NET WinForms components
include True DBGrid for .NET,
FlexGrid for .NET, Reports for .NET,
Preview for .NET, Chart for .NET,
DataObjects for .NET, Input for .NET,
List for .NET, Zip for .NET, Menus
and Toolbars for .NET, and Spell
for .NET. ASP.NET WebForms
components include WebGrid
for ASP.NET, WebReports for
ASP.NET, WebChart for ASP.NET,
WebDataObjects for ASP.NET,
WebMenus and WebBars for ASP.NET,
and PayPal eCommerce for ASP.NET.
ComponentOne LLC
Price: Full version, US$899.95. Owners of Borland
C#Builder for the Microsoft .NET Framework, or any
APEX, VideoSoft, or ComponentOne product, can
upgrade to ComponentOne Studio Enterprise for
US$599.95.
Contact: info@componentone.com
Web Site: www.componentone.com/borland
G R E A T E R
JAVA NATIVE INTERFACE
JAVA
D E L P H I
JBUILDER
DELPHI 6, 7
By Keith Wood
Going Native
Part 1: Using the Java Native Interface with Delphi
Delphi Type
Type Name
Signature
boolean
Boolean
JBoolean
byte
ShortInt
JByte
char
WideChar
JChar
double
Double
JDouble
float
Single
JFloat
int
Integer
JInt
long
Int64
JLong
short
SmallInt
JShort
void
N/A
N/A
Some reasons that you might want to call native code from
Java include: gaining access to platform-specific features not
available in Java, reusing existing code libraries already in
native format for which you do not have the source code or the
time to port, or for running time-critical or CPU-hungry routines in a faster environment. Similarly, you may want to call
Java from native code to use existing packages and APIs, or to
gain access to Java-specific constructs, such as RMI and EJBs.
Although originally developed with C and C++ as the
target native languages, the efforts of Matthew Mead have
produced a Pascal translation of the JNI suitable for use in
Delphi. The package is available from Matthews Web site
(see the References section at the end of this article).
Included in the package are several examples and tutorials
to get you started.
Java Types
Communication between the two environments consists
of making method calls and passing parameters back and
forth. The arguments may be either primitive types or complete objects. Obviously there needs to be some mapping
between the basic types in Java and those in Delphi to facilitate their transfer. The JNI.pas and JNI_MD.inc files contain
these mappings, as shown in Figure 1. So, wherever you use
a particular type in Java, you should use the corresponding
J* type defined in Delphi. Behind the scenes these are just
renamings of the associated basic Delphi types.
Every other type is passed generically as an object and is
referred to in Delphi as JObject. Several renamings of this
base type appear, including JString, JClass, and JArray (and
its derivatives).
Associated with each type is a signature character. This
short form is used to identify types for fields, and for the
return and parameter types of methods. Class types have
Greater
Delphi
Going Native
package mypkg;
public class MyClass {
static {
System.loadLibrary("MyLib");
}
public native void doIt(String message);
}
Every routine must take at least two parameters: a reference to the JNI environment, and a reference to the
object making this call (or class if static). Additional
parameters are included to match those of the Java declaration. Also, the routines must follow the standard library
calling convention for the platform: stdcall on Windows
or cdecl on Linux. Thus, the full Delphi signature for the
doIt method defined in Figure 2 is:
procedure Java_mypkg_MyClass_doIt(PEnv: PJNIEnv;
Obj: JObject; message: JString);
{$IFDEF WIN32} stdcall; {$ENDIF}
{$IFDEF LINUX} cdecl; {$ENDIF}
Java_java_lang_Object_getClass
in Delphi, and the overloaded wait routine from the Object class:
becomes:
Java_java_lang_Object_wait__J
Greater
Delphi
Going Native
returns:
'(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;ID)V'
Greater
Delphi
Going Native
package wood.keith.djniexample;
/* Demonstrate JNI access to Delphi library. */
public class Example1 {
static {
System.out.println("Library path: " +
System.getProperty("java.library.path"));
// Load the native library.
System.loadLibrary("wood_keith_djniexample_Example1");
}
public Example1() {}
/* Display the message to the console.
* @param message the text to display */
public static native void printMessage(String message);
/* Find all BioLife database records.
* @return an array of matching BioLife records,
*
empty if none
*/
public native BioLife[] getBioLife();
*/
Greater
Delphi
Going Native
10
Greater
Delphi
Going Native
11
SQL.Text
:= 'select BioLife."Species No", ' +
'Category, Common_Name, BioLife."Species Name", ' +
'BioLife."Length (cm)", Length_In ' +
'from BioLife where ' + QueryWhere;
Open;
if RecordCount = 0 then begin
JVM.ThrowNew(
ExceptionClass, 'No matching fish found');
Exit;
end;
// Create the result array.
Result := JVM.NewObjectArray(
RecordCount, BioLifeClass, nil);
Index := 0;
while not EOF do begin
// Create a BioLife object and populate it.
{$IFDEF JNIUTILS}
BioLifeObj := JNIUtils.CreateObject(JVM,
'wood.keith.djniexample.BioLife',
'void (int, String, String, String, int, double)',
[FieldByName('Species No').AsInteger,
FieldByName('Category').AsString,
FieldByName('Common_Name').AsString,
FieldByName('Species Name').AsString,
FieldByName('Length (cm)').AsInteger,
FieldByName('Length_In').AsFloat]);
{$ELSE}
BioLifeObj := JVM.NewObjectA(BioLifeClass,
ConstructorId, JVM.ArgsToJValues(
[FieldByName('Species No').AsInteger,
FieldByName('Category').AsString,
FieldByName('Common_Name').AsString,
FieldByName('Species Name').AsString,
FieldByName('Length (cm)').AsInteger,
FieldByName('Length_In').AsFloat]));
{$ENDIF}
if not Assigned(BioLifeClass) then
Exit;
// Add it to the array.
JVM.SetObjectArrayElement(
Result, Index, BioLifeObj);
Inc(Index);
Next;
end;
Close;
end;
finally
BioLifeQuery.Free;
end;
end;
{ Java declaration: public native
wood.keith.djniexample.BioLife[] getBioLife()
Class: wood.keith.djniexample.Example1
Method: getBioLife
Signature: ()[Lwood/keith/djniexample/BioLife;
Find all BioLife records. }
function
Java_wood_keith_djniexample_Example1_getBioLife__(
PEnv: PJNIEnv; Obj: JObject; Category: JString):
JObjectArray; {$IFDEF WIN32} stdcall; {$ENDIF}
{$IFDEF LINUX} cdecl; {$ENDIF}
var
JVM: TJNIEnv;
begin
JVM := TJNIEnv.Create(PEnv);
try
Result := searchBioLife(
JVM, 'BioLife."Length (cm)" > 0');
finally
JVM.Free;
end;
end;
{ Java declaration: public native
Greater
Delphi
Going Native
wood.keith.djniexample.BioLife[]
getBioLife(java.lang.String)
Class: wood.keith.djniexample.Example1
Method: getBioLife
Signature: (Ljava/lang/String;)
[Lwood/keith/djniexample/BioLife;
Find BioLife records like a given category. }
function Java_wood_keith_djniexample_Example1_
getBioLife__Ljava_lang_String_2(
PEnv: PJNIEnv; Obj: JObject; Category: JString):
JObjectArray; {$IFDEF WIN32} stdcall; {$ENDIF}
{$IFDEF LINUX} cdecl; {$ENDIF}
var
JVM: TJNIEnv;
begin
JVM := TJNIEnv.Create(PEnv);
try
Result := searchBioLife(JVM, 'Category like "%' +
JVM.JStringToString(Category) + '%"');
finally
JVM.Free;
end;
end;
{ Java declaration: public native
wood.keith.djniexample.BioLife[] getBioLife(int, int)
Class: wood.keith.djniexample.Example1
Method: getBioLife
Signature: (II)[Lwood/keith/djniexample/BioLife;
Find BioLife records with length (cm) in a given range. }
function
Java_wood_keith_djniexample_Example1_getBioLife__II(
PEnv: PJNIEnv; Obj: JObject; MinLength: JInt;
MaxLength: JInt): JObjectArray;
{$IFDEF WIN32} stdcall; {$ENDIF}
{$IFDEF LINUX} cdecl; {$ENDIF}
var
JVM: TJNIEnv;
begin
JVM := TJNIEnv.Create(PEnv);
try
Result := searchBioLife(JVM, 'BioLife."Length (cm)" ' +
'between ' + IntToStr(MinLength) +
' and ' + IntToStr(MaxLength));
finally
JVM.Free;
end;
end;
exports
// Make the routines available for external use.
Java_wood_keith_djniexample_Example1_printMessage,
Java_wood_keith_djniexample_Example1_getBioLife__,
Java_wood_keith_djniexample_Example1_getBioLife__
Ljava_lang_String_2,
Java_wood_keith_djniexample_Example1_getBioLife__II;
end.
12
. N E T
ASP.NET
T E C H
DELPHI 7
Description
System.Data
A set of core ADO.NET classes, including classes (e.g. DataSet), that make up
the disconnected part of the data access
architecture.
System.Data.Common
System.Data.SqlClient
System.Data.OleDb
System.Data.SqlTypes
System.Xml
13
.NET
Te c h
on the client, you can use any list-bound Web Server control, such as Repeater, DataList, or DataGrid.
Using the Repeater Control
The Repeater control is the simplest data binding Web Server
control available in ASP.NET. We use this control to display a
list of records from a database table and we can specify a template that can be applied to each item displayed in the list.
We can use five templates that define how the header
(HeaderTemplate), item itself (ItemTemplate), separator
(SeparatorTemplate), and footer (FooterTemplate) should
be displayed on the page. If we want a different appearance
for alternating (odd-indexed) items in the table, create
AlternatingItemTemplate with the same contents as
14
<html>
<head>
<title>Repeater example</title>
</head>
<body>
<form id="main" runat="server">
<asp:Repeater id = "Rpt" runat="server">
<HeaderTemplate> <table border=2>
<tr>
<td><b>Name</b></td>
<td><b>Title</b></td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr><td>
<%# DataBinder.Eval(Container.DataItem,'FirstName')%>
<%# DataBinder.Eval(Container.DataItem,'LastName')%>
</td><td>
<%# DataBinder.Eval(Container.DataItem,'Title')%>
</td></tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</form>
</body>
</html>
.NET
Te c h
<ItemTemplate>
<tr><td>
<%# DataBinder.Eval(Container.DataItem,'FirstName')%>
<%# DataBinder.Eval(Container.DataItem,'LastName')%>
</td><td>
<%# DataBinder.Eval(Container.DataItem,'Title')%>
</td></tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr bgcolor="#c0c0c0"><td>
<%# DataBinder.Eval(Container.DataItem,'FirstName')%>
<%# DataBinder.Eval(Container.DataItem,'LastName')%>
</td><td>
<%# DataBinder.Eval(Container.DataItem,'Title')%>
</td></tr>
</AlternatingItemTemplate>
15
.NET
Te c h
<asp:DataList
Control properties are specified here.
<HeaderStyle BackColor = "#a7b7c7"
HorizontalAlign = "Center" Font-Size = "Large">
<ItemStyle BackColor="#d0d0d0">
Templates are specified here.
/asp:DataList>
.NET
Te c h
.NET
Te c h
procedure LoadData();
var
Conn : SqlConnection;
DA : SqlDataAdapter;
DS : DataSet;
begin
Conn := SqlConnection.Create(
'server=localhost;database=Northwind;uid=sa;pwd=');
DA := SqlDataAdapter.Create(
'SELECT * FROM Products', Conn);
DS := DataSet.Create;
DA.Fill(DS, 'Products');
Grid.DataSource := DS;
Grid.DataBind();
end;
procedure PageProduct(Sender: TObject;
e: DataGridPageChangedEventArgs);
begin
Grid.CurrentPageIndex := e.NewPageIndex;
LoadData();
end;
</script>
<html>
<head>
<title>DataGrid</title>
</head>
<body>
<form runat="server">
<asp:DataGrid id = "Grid" HeaderStyle-BackColor="#c0c0c0"
AutoGenerateColumns = "False" AllowPaging="True"
OnPageIndexChanged="PageProduct" runat="server">
<PagerStyle Mode="NumericPages"
HorizontalAlign="Center"/>
<Columns>
...
</Columns>
</asp:DataGrid>
</form>
</body>
</html>
.NET
Te c h
19
Conclusion
In this article we discussed creating ASP.NET applications
with the Delphi Compiler for Microsoft .NET. We created
examples that illustrate data binding using the Repeater,
DataList, and DataGrid controls, and we illustrated how to
display, highlight, select, edit, sort, and page data.
The 10 ASPX pages that support this article are available for
download on the Delphi Informant Magazine Complete
Works CD located in INFORM\2003\SEP\DI200309AF.
.NET
Te c h
20
</form>
</body>
</html>
I N
OOP
D E V E L O P M E N T
ENCAPSULATION
DELPHI 1-7
By Peter Gatis
21
In
Development
Weakly Encapsulated
Strongly Encapsulated
Semantic Encapsulation
The definitions in Figure 1 use the formidable word semantic to raise the level of discussion to the meaning of each
public (or published) declaration, and to provide the analytic wedge by which we may separate implementation code
from the intelligibility of the class definition. We also use
the term Universe of Discourse to restrict our thoughts to an
arbitrary set of objects and their proper attributes (as we
might find in an ordinary application). Were disregarding
such constructs as class functions or global variables. The
definition of semantic encapsulation tells us we can ignore
the implementation code of a class when the interface is
complete and understandable.
To clarify semantic encapsulation a little further, the semantic value of an item refers to its meaning and truth-value, or
validity. For example, a pointer is valid or invalid depending
on the value it contains and the context of its use. To speak
of the semantic value of a pointer makes this explicit:
1) A pointer may be either valid or invalid (the domain of
accepted truth-values).
2) A pointer must be either valid or invalid, if the pointer
exists at all.
3) A pointer cannot be both valid and invalid.
If any of these conditions fail, the pointer has no semantic
value, and were unable to speak about it meaningfully
without embracing difficult qualifications. Similar logic
applies to procedures, functions, and properties. Note that
existence and validity are not the same thing, but that existence is a necessary condition of validity.
Semantic encapsulation separates two distinct but related
definitions of encapsulation into strong and weak flavors.
Strong encapsulation is the limiting case of weak encapsulation. The definition implies that weak encapsulation can be
progressively bolstered through mechanical encapsulation
until it reaches our preferred strong encapsulation. Strong
encapsulation combines semantic and mechanical encapsulation in a satisfying union, i.e. we can make our black box
with solid sides.
Computer Science lecturers, computer dictionaries, and programming texts generally speak of any encapsulation as if it
were strong encapsulation. Clearly, this is a mistake; we have
no automatic reason to assume that any class defined unto
itself is already strongly encapsulated. Maintenance coders
will attest that strong encapsulation is in fact a rarity.
Often the best we can hope for are class definitions that prevent accidental misuse of the class. Nothing can stop a deliberate or misguided attempt to break weak encapsulation.
22
// Write removed.
TParser = class(TObject)
public
property InputString: string write SetInputString;
property RealValue: extended read GetValue;
end;
In
Development
:=
:=
:=
:=
TMyObject(MyObjectIdAsObject);
TMyObject(MyObjectIdAsInteger);
TMyObject(MyObjectIdAsPointer^);
TMyObject(MyObjectIdAsAddress^);
In
Development
Violations
What about encapsulation violations? The following
examples illustrate encapsulation violations; they can be
extended indefinitely, and any given example could be
(but isnt) discussed at length.
Direct violations of mechanical encapsulation:
Failure to access private variables exclusively through
functions and procedures.
Failure to segregate class definitions into separate units.
Direct violations of weak encapsulation:
Providing an incomprehensible interface.
Providing properties that change value depending on the
order of access.
Direct violations of strong encapsulation:
Interlinking object references without safeguards.
Defining the validity of an attribute with respect to an
inherited class.
Theres no easy way out. Just as strong semantic encapsulation is the limiting case of weak semantic encapsulation,
ENF is the limiting case of our testing procedures. We canDirect violations of ENF:
not test everything, but we can show that the tests we do
Injecting a value directly into a private variable by priperform are at least consistent. We allow that test cases
vate address.
cannot be exhausted. We can fix the undefined quantities,
Substituting out event handlers created within the object.
the inaccurate results, the inconsistent values, the lack of
precision, the unmet boundary conditions, and still have
Bringing Them Together
an isolated exception blow sky high after the application
As we said earlier, semantic encapsulation applies to the
gets into production. If our test cases circumscribe the
class definition itself, not to instantiated objects. ENF, in its
ordinary circumstances of
turn, applies to instantiated
object use, we can at least
objects, but not particularly
We are at times obliged to
say that ENF has held up
to class definitions. Can we
link objects together. When this
under specified testing. Perforge a connection between
haps the best a quality prodthe two? Having two separate
happens, it appears there is
uct can do is fall within its
categories of encapsulation is
no way to preserve the strict
own testable specifications.
a little unsettling. How do we
integrity of encapsulation.
know the two are not mutually
Remember the Musketeers
exclusive? For the mathematiCreed: All for one and one for all. The Creed summarizes
cally inclined, see the sidebar Encapsulation Relation Proof
the relationship of object id to public attributes within
of the Equivalence of Semantic Encapsulation and ENF for
encapsulated normal form. If any public attribute is valid,
proof of the logical equivalence of the two.
the object id must be valid (all for one), and if the object id
is valid then all the public attributes must be valid (one for
Although the idea that black-box design might have a physiall). On the force of the Musketeers Creed, we might not be
cal counterpart is pretty exciting, one particular problem
able to prove that ENF succeeds, but we can prove to any
jumps out as the crucial application of encapsulation: We
degree of certitude that it doesnt fail. Conversely, where
are at times obliged to link objects together. When this hapthe Musketeers Creed fails, our object has an encapsulation
pens, it appears there is no way to preserve the strict integfracture line.
rity of encapsulation. The validity of the reference is bound
to be directly dependent on the validity of the pointer, i.e.
Further comments are in order. We have used the phase at
the object id of a completely different object. How we define
all times to reinforce the idea that ENF can be broken after
our class interface has no bearing on whether another object
the object has been instantiated. An object can be bullied by
has to exist, unless we also link our class semantics togethanother object into giving up its validity either by misusing
er. This could beat encapsulation altogether.
the intended interface, or by by-passing the intended interface
altogether (see Breaking Encapsulation in the July 2003
We can use the equivalence of semantic encapsulation and
issue of Delphi Informant). As maintenance coders facing an
ENF to show how object interlinking breaks encapsulation
object whose behavior has gone berserk, we may legitimately
(see the reference to subcase 2 in the sidebar). Figure 7
ask whether the integrity of the object has been sustained,
illustrates a simple interlinking where every TChild object
or whether the object has been abused along the way. The
has two TParent objects. The interlinking seems natural
object id remains our key to such a situation: A public attribute enough. As expected, we have a situation where the validity
whose validity depends on an interloper object id has clearly
of an attribute (mother or father) depends on the existence
gone out of bounds. ENF imposes limits.
of an externally referenced object, i.e. a semantic determi-
24
In
Development
interface
type
TParent = class(TObject)
private
FChildren: TList;
public
property Children: TList read FChildren;
end;
TChild = class(TObject)
private
FMother: TParent;
FFather: TParent;
procedure SetMother(ANewVal: TParent);
function GetMother: TParent;
procedure SetFather(ANewVal: TParent);
function GetFather: TParent;
public
constructor Create;
destructor Destroy; override;
property Mother read GetMother write SetMother;
property Father read GetFather write SetFather;
end;
TContextOfUse = class(TObject)
public
// Strong encapsulation breaks here.
procedure AssignParentsToChildren;
end;
25
In
Development
26
{$R *.DFM}
{ TMyObject1 }
procedure TMyObject1.InterfereWithMyObject2;
begin
Form1.FMyObj2.FValue2 := 13;
end;
{ TMyObject2 }
procedure TMyObject2.InterfereWithMyObject1;
begin
Form1.FMyObj1.FValue1 := 17;
end;
{ Form events. }
procedure TForm1.Button1Click(Sender: TObject);
begin
FMyObj1.InterfereWithMyObject2;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FMyObj2.InterfereWithMyObject1;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
FMyObj1 := TMyObject1.Create;
FMyObj2 := TMyObject2.Create;
end;
procedure TForm1.FormDeactivate(Sender: TObject);
begin
FMyObj1.Destroy;
FMyObj2.Destroy;
end;
end.
INFOR MAN T
SPO TLI GH T
By Jerry Coffey
Best Add-in
Add-in redux. This category
is a near carbon copy of last
years results, with the same
products finishing first, second,
and third. Developer Express
CodeRush (purchased recently
from Eagle Software) took first
place for the fifth straight year,
with 36% of the votes. ModelMaker Code Explorer (from
ModelMaker Tools) took runner-up with 19%, and Multi-Edit
from American Cybernetics took
third with 12%.
CodeRush (36%)
ModelMaker
Code Explorer (19%)
Multi-Edit (12%)
Athlant (11%)
Castalia (8%)
other (14%)
Informant
Spotlight
Best Book
teeChartPro (59%)
ExpressOrgChart
Suite (18%)
Chart FX (8%)
TatukGIS (7%)
other (8%)
Advantage TDataSet
Descendant
(20%)
FIBPlus (15%)
IB Objects (13%)
Asta (11%)
Oracle Data Access
Components (10%)
Direct Access Components
for MySQL (9%)
Direct Oracle Access
Component Set (8%)
kbm MW (7%)
other (7%)
DBISAM Database
System (40%)
Advantage Database
Server (28%)
Apollo (9%)
TOPAZ for Delphi (7%)
Pervasive SQL (6%)
other (10%)
Its also interesting to note how these two products are taking
a higher percentage of the total votes. Advantage and DBISAM
combined for 53% of the vote in 2001, and 54% in 2002, but
this year they teamed up to take 68%. This would appear to
indicate that they have moved into the vacuum left by TurboPowers FlashFiler, last years third-place finisher with 20%.
Apollo took third place this year with 9% (down from 15% last
year), with Software Sciences TOPAZ for Delphi nipping at its
heels in fourth place with 7%.
IB Expert (21%)
InfoPower (20%)
ExpressQuantumTreeList
(16%)
EhLib (8%)
MySQL Manager (7%)
Rubicon Text Search (6%)
other (22%)
CodeSite (33%)
AQTime (27%)
NuMega
BoundsChecker (15%)
ProDelphi
Professional (9%)
other (16%)
Informant
Spotlight
Best Library
InstallShield (52%)
Wise for Windows
Installer (33%)
Ghost Installer Studio (7%)
Other (8%)
ModelMaker (54%)
Rational Rose (19%)
CDK (12%)
other (15%)
ReportBuilder (37%)
FastReport (29%)
Rave BEX (Borland
Edition EXtended) (15%)
QuickReport
Professional (7%)
Express Printing
System (6%)
other (6%)
Informant
Spotlight
Best Scheduling/Calendar
Critical path confirmed. This
category enters its second
year with the same winner
and runner-up. TMS TPlanner/
TDBPlanner (TMS Software)
took first place with 63%
(building on last years 51%),
while Jazmine Calendar/PIM
Widgets (Jazmine Components)
took second place again with
17% (virtually the same as last
years 18%).
TMS TPlanner/
TDB Planner (63%)
Jazmine Calendar/
PIM Widgets (17%)
other (20%)
Best Utility
Best Training
TestComplete (60%)
DevPartner Studio (18%)
Rational Robot (18%)
ANTS Load (4%)
ASPack (23%)
VMware Workstation (23%)
Beyond Compare (16%)
FinalBuilder (12%)
Xceed Zip (9%)
other (17%)
ExpressQuantumGrid (43%)
TAdvStringGrid (16%)
UIL Time Framework (7%)
VCLZip (6%)
TRich View (6%)
other (22%)
Informant
Spotlight
IntraWeb (62%)
ExpressWeb
Framework (25%)
PackageForThe Web (5%)
other (8%)
Your new choice for Product of the Year is Help & Manual
from EC Software. The number two spot changed hands
as well, with ExpressQuantumGrid (Developer Express)
replacing Advantage Database Server. Just for fun, here
are the products that placed first and second as POY over
the years:
1996 InfoPower, (unknown)
1997 InfoPower, Orpheus
1998 InfoPower, Apollo
1999 ReportBuilder, Orpheus
2000 ReportBuilder, Apollo
2001 ReportBuilder, Advantage Database Server
2002 ReportBuilder, Advantage Database Server
2003 Help & Manual, ExpressQuantumGrid
Hats Off!
As always, I thank the tireless Delphi third-party vendors who
create the products that are the subject of these awards. Without these entrepreneurs who are willing to risk their time and
effort each year, there would be no Delphi community. And,
of course, I thank all of you in the Delphi community for voting. We received the most votes ever this year, which is pretty
amazing since there are fewer of you using Delphi than when
we started the awards in 1996. Youre a more devoted group
now, however, and that makes all the difference.
31
N E W
&
U S E D
ExpressQuantumGrid 4
More than an Excellent Grid
Figure 2: The main component editor allows you to add, delete, and set the
properties of a grids columns.
32
Figure 1: The grid provides easy access to the main component editor, and
access to sub-components on the Object Inspector and other editors by clicking
or right-clicking to bring up context menus.
New
&
Used
ExpressQuantumGrid 4
Figure 3: The Layout Editor provides an intuitive interface for setting up the
appearance of a grid.
Figure 4: This dialog box uses standalone editors and shows the flat look.
New
&
Used
ExpressQuantumGrid 4
Figure 5: The main form shows the grid with a group box and button, all using
the ultra-flat look.
TcxMRUEdit An MRU (most recently used) text editor that stores the
most recently inputted strings in its associated drop-down list.
TcxNavigator A navigator control that can manage external controls that dont have an assigned dataset.
TcxExtLookupComboBox A combobox that displays a dataaware grid view in its drop-down window, allowing the user to
select a record.
TcxTextEdit An enhanced single-line text editor that allows selecting text within the text editor, copying or cutting the selection to the
clipboard, and special functions such as entered value validation or
automatic completion functionality.
Figure 6: Editors and controls that enhance the work of the grid.
34
New
&
Used
ExpressQuantumGrid 4
35
Conclusion
This is one component library that lives up to all the praise
it has received. The only problem I encountered in working
with a mask edit control was quickly solved by personnel at
Developer Express. Download the executable program and
the source code for the testing application I wrote and give it
a spin. And be sure to visit the Developer Express Web site
and download some of the excellent demonstrations.
An application that demonstrates the mask edit control (on a
grid and as a separate edit control) is available for download
on the Delphi Informant Magazine Complete Works CD
located in INFORM\2003\SEP\DI200309AM.
F I L E
N E W
File
New
Abbrevia (sourceforge.net/projects/
tpabbrevia) provides compression
functionality, and supports PKZIP
4, Microsoft CAB, TAR, and gzip
File
New
38
Alan Moore is a professor at Kentucky State University, where he teaches music theory and humanities. He
was named Distinguished Professor for 2001-2002. He has been named the Project JEDI Director for 2002-2004.
He has developed education-related applications with the Borland languages for more than 15 years. Hes the
author of The Tomes of Delphi: Win32 Multimedia API (Wordware Publishing, 2000) and co-author (with
John C. Penman) of The Tomes of Delphi: Basic 32-Bit Communications Programming (Wordware Publishing,
2003). He also has published a number of articles in various technical journals. Using Delphi, he specializes in
writing custom components and implementing multimedia capabilities in applications, particularly sound and
music. You can reach Alan at acmdoc@aol.com.