Professional Documents
Culture Documents
Blaise 19UK PDF
Blaise 19UK PDF
Blaise 19UK PDF
Pascal
19
Procedure Speech(Sender:TMonkey)
Begin
Monkey := 'Hello World';
End;
November 2011
Publisher: Foundation for Supporting the Pascal Programming Language
in collaboration with the Dutch Pascal User Group (Pascal Gebruikers Groep)
Stichting Ondersteuning Programmeertaal Pascal
BLAISE
PASCAL MAGAZINE 19
ALL ABOUT DELPHI AND DELPHI PRISM(.Net), LAZARUS & PASCAL AND RELATED LANGUAGES
CONTENTS
Articles
Editor - in - chief
A
B
C
D
F
G
H
J
L
M
N
O
P
R
S
Alexander Alexeev
Peter Bijlsma,
Michal Van Canneyt, Marco Cant,
David Dirkse, Daniele Teti
Bruno Fierens
Primo Gabrijeli,
Fikret Hasovic
Cary Jensen
Wagner R. Landgraf, Sergey Lyubeznyy
KIm Madsen, Felipe Monteiro de Cavalho
Jeremy North,
Tim Opsteeg, Inoussa Ouedraogo
Howard Page-Clark, Herman Peeren,
Michael Rozlog,
Henk Schreij, Rik Smit, Bob Swart,
Editors
Peter Bijlsma, Rob van den Bogert, W. (Wim) van
Ingen Schenau,
Correctors
Howard Page-Clark, James D. Duff
Copyright Page 118
Trademarks All trademarks used are
acknowledged as the property of their respective
owners.
Caveat Whilst we endeavour to ensure that what
is published in the magazine is correct, we cannot
accept responsibility for any errors or omissions. If
you notice something which may be incorrect,
please contact the Editor and we will publish a
correction where relevant.
Subscriptions ( 2011 prices )
1: Printed version: subscription 60.-(including code, programs and printed magazine,
4 issues per year including postage).
2: Non printed subscription 35.-(including code, programs and download
magazine)
Subscriptions can be taken out online at
www.blaisepascal.eu
or by written order, or by sending an email to
office@blaisepascal.eu
Advertisers
Advantage Database Server page 3
AnyDac page 27 / 28
Barnsten page 20
Bauer + Kirch page 5
BitTime page 36
Cary Jensens newest book page 52
Components for Developers page 60
Database Workbench Pro- Upscene Productions page 45
FastCube page 25
FastReport page 26
LAZARUS Book page 19 / 42
Subscription department
Edelstenenbaan 21 / 3402 XA IJsselstein,
The Netherlands / Tel.: + 31 (0) 30 890.66.44 /
Mobile: + 31 (0) 6 21.23.62.68
office@blaisepascal.eu
COMPONENTS
DEVELOPERS
Foreword
This issue specially finished for the First Belgian
Delphi event: Be-Delphi - is as we hope, the first start
of
a long series of events for Belgium.
In the next issue (December) we will let you know all
about the happenings over here. Meanwhile we have
published issue No.18, (the Dutch issue 100)
containing 126 pages. A real milestone.
There is another major milestone to be celebrated
next year. Blaise Pascal Magazine will have been
created 25 years ago, and part of the celebration
during the year 2012 will be enjoyed by making it
even more attractive to our readers.
We will publish our Essential Pascal Learning and
teaching book - Marco Cant is one of the Authors for the first time in English. We will create an Adobe
Pdf version and a Loose Leaf version.
There is a very special thing about this:
there will be about a hundred sample programs
coming with it and, because we do the complete IDE
of Delphi as Lazarus, you will be able to regularly
update your issue with the newest version of Delphi
or Lazarus.
And of course it will be in full colour. You can
subscribe to it and it will cost 50 Euros per year.
Full details will be published next year on our
website.
I hope you all will find it very attractive.
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
expert
DELPHI XE2
Figure 1: We go through the expert and select Stand-Alone VCL application in this case:
6
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
type
TServerMethods1 = class(TDataModule)
MyDB: TSQLConnection;
MyDS: TSQLDataSet;
private
{ Private declarations }
public
{ Public declarations }
function GetRecordCount: Integer;
procedure GetRecord(RecNo: Integer;
var FirstName, LastName: String);
function GetRecords : TJSONArray;
end;
Finally, for comparison, I include another method GetRecords - that returns all of the records as a
TJSONArray.
It also has a comment section that describes how to get the
data back out of the array on the Win/Mac side (different
code applies to iOS).
Figure 6:
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
Figure 12:
COMPONENTS
DEVELOPERS
11
unit Unit1;
{$IFDEF FPC}
{$modeswitch ObjectiveC1}
{$ENDIF}
cmd.setText(NSSTR(PChar('TServerMethods1.GetRecordCou
12
COMPONENTS
DEVELOPERS
cmd.prepare(NSArray.arrayWithObjects(
DSRESTParameterMetaData.
parameterWithName_withDirection
_withDBXType_withTypeName(
NSSTR(PChar(String(''))),4{ReturnValue},
Int32Type,NSSTR(PChar(String('Int32')))),
nil
));
Finally, we extract the return value and return it from our function:
Result := cmd.getParameterByIndex(0).getValue.GetAsInt32;
end;
Now for the "easy" part: actually calling our methods and
getting that data displayed in our client. Notice that the
first thing we do here is create and set up the DataSnap
connection. We provide the host address, the port, and the
protocol to be used.
We then call GetRecordCount and iterate over all records
to get them displayed in our UI.
procedure TForm1.GetDataButtonClick(Sender: TObject);
var
i : Integer;
FirstName, LastName : String;
begin
Connection := DSRESTConnection.alloc.init;
Connection.setConnectionTimeout(5);
Connection.setHost(NSSTR(PChar(String(HostEdit.Text))));
Connection.setPort(StrToInt(PortEdit.Text));
Connection.setProtocol(NSSTR(PChar(String('http'))));
for i := 0 to GetRecordCount-1 do begin
GetRecord(i,FirstName,LastName);
Memo1.Lines.Add(LastName+', '+FirstName);
end;
end;
end.
COMPONENTS
DEVELOPERS
13
14
COMPONENTS
DEVELOPERS
Resources
COMPONENTS
DEVELOPERS
15
expert
Combining these classes with existing fcl-web components The simplest webserver can be implemented with very few lines of code:
allows you to create a fully-fledged HTTP server, which can program myserver;
serve files, implement a web application, or host a web
service for WST (the Web Services Toolkit as explained in uses
SysUtils, fphttpapp, fpwebfile;
the book, Lazarus The Complete Guide). All this can be
achieved with a standard Free Pascal and Lazarus (latest
Const
MyPort = 8080;
version only) installation.
MyDocumentRoot = '/home/michael/public_html';
These networking components are architecturally simple,
MyMiMeFile = '/etc/mime.types';
so they may not be suitable to build high-load, scalable
web servers. But they are perfectly suitable for simple web begin
RegisterFileLocation('files',MyDocumentRoot);
services or embedded use.
MimeTypesFile:=MyMimeFile;
There are two basic components available:
TFPHTTPServer This is the component that does the
actual work. It offers various properties for configuring
the server. The most important ones are the TCP/IP
port number to listen to (obviously named Port), and the
Active property, which starts the server. It also offers an
event to actually handle requests, named OnRequest
(what else?). When embedding an HTTP server in an
application, this is the component you should use.
This is a TCustomApplication
descendant which uses a THTTPServer component to
listen to requests, and then hands the requests over to
the fcl-web request dispatcher mechanism. This
component should be used when creating a web service
hosting application. It offers the same properties as the
THTTPServer component for configuring the server's
behaviour.
THTTPApplication
16
COMPONENTS
DEVELOPERS
Application.Initialize;
Application.Port:=MyPort;
Application.Title:='My HTTP Server';
Application.Run;
end.
COMPONENTS
DEVELOPERS
17
procedure TMainForm.ShowURL;
begin
MLog.Lines.Add('Handling request : '+FURL);
end;
Note that the URL which is entered, does not contain the
location 'files' as in the first demo. The reason is that
the application does not need to decide which fcl-web
module is needed to handle the request, because all
requests are handled by the file-serving module. When this
module was created in the OnCreate handler of the main
form, the line
FHandler.BaseURL:='files/';
COMPONENTS
DEVELOPERS
LAZARUS
THE COMPLETE GUIDE
Simple Package 35,00
(this excludes shipping costs 17.50)
- Just the book and a Windows installer CD
for Lazarus value 12.50
- 50 additional sample projects
- extra: additional prenstalled component suites
barnss en
DEVELOPMENT &
DATABASE
28
42
20
TOOLS
expert
DELPHI XE2
COMPONENTS
DEVELOPERS
21
iFeeed :=
AzureTableXmlInterfaces.Getfeed(XmlDocument1);
for I := 0 to iFeeed.Entry.Count - 1 do
begin
// process XML node by reading XML elements
end;
procedure TS3ClientForm.btnListBucketsClick(Sender:
TObject);
var
sBucketsList: TStrings;
I: Integer;
item: TListItem;
begin
lvBuckets.Clear;
sBucketsList := s3Service.ListBuckets;
for I := 0 to sBucketsList.Count -1 do
begin
item := lvBuckets.Items.Add;
item.Caption := sBucketsList.Names[I];
item.SubItems.Add(sBucketsList.ValueFromIndex[I]);
// CreationDate
end;
end;
COMPONENTS
DEVELOPERS
As you can see the code is quite simple and linear, and
(again) this is very different from the manual processing
code I used earlier, based on some sophisticated XML
processing. Now I don't want to continue listing the
remaining methods in such detail, but only cover the key
features. The program, in fact, has quite a few features.
One area is buckets management, with the possibility of
creating new buckets and deleting
existing ones. The calls are quite simple:
var
FileContent: TBytes;
fReader: TBinaryReader;
begin
fReader := TBinaryReader.Create(
OpenPictureDialog1.FileName);
FileContent :=
fReader.ReadBytes(fReader.BaseStream.Size);
s3Service.CreateBucket(edBucketName.Text);
s3Service.DeleteBucket (CurrentBucketName);
COMPONENTS
DEVELOPERS
23
Figure 4: The repository hosting the code of the projects covered in this article.
The global subversion repository and the project specific one (these are the URL you can put in Delphi's File | Open
From Version Control command) are at the following URLs:
http://code.marcocantu.com/svn/marcocantu/delphirestclients
http://code.marcocantu.com/svn/marcocantu/delphirestclients
You can also browse the project source code online, if all you are interested in is looking at it. Use the Source | Source
Tree commands from the initial URL above and follow the specific project, called AmazonS3_XE2.
At the same repository you can also find other Delphi REST clients I wrote, including the AmazonS3Client project, the
older version of the same client, based on a custom component. Other projects include a simple RSS feed, a Twitter
search client, and a Google Translate client.
Remember you need to create your own Amazon Web Services account and prepare the INI file with the account key
and secret key to see the program up and running.
About the Author:
Marco Cant is the author of several best-selling
Delphi books, including the Mastering Delphi series
and the recent Delphi Handbook series (the last
being a Delphi XE Handbook) all available in the
Delphi Handbooks Collection ebook. He's also an
active user and developer in the Web 2.0 world and
social web, like Twitter and Google+. You can reach
him on www.marcocantu.com or on
blog.marcocantu.com, and email him at
marco.cantu@gmail.com.
24
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
25
26
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
27
AnyDAC is an unique set of Universal Data Access Components for developing database applications on Delphi,
C++Builder and FreePascal. With its powerful common architecture AnyDAC enables native high-speed direct
access from Delphi to Firebird, SQLite, MySQL, SQL Server, Oracle, PostgreSQL, DB2, SQL Anywhere,
Advantage DB, Interbase, Access, Informix and more.
Based on 10 years of experience writing native drivers for the database back-ends, AnyDAC was built as
powerful access layer that supports all that the features needed to build real-world high-load applications.
AnyDAC provides a common API for accessing different database back-ends, without giving up access to unique
database-specific features, or compromising on performance.
Technology Consulting
The main objective is to provide the customers with competent technology advice that provides an optimal
approach to implementation and deployment of the software system.
Software Development
DA-SOFT Technologies is a company that creates, designs and develops technology to deliver measurable
results with direct impact on your bottom line. After an analysis of your unique needs and operations, we
employ the right tools to manage your task.
Application Maintenance
As clients strive to integrate their business and IT strategies, our application maintenance services help them
achieve their business goals and objectives, by providing on-time support and value adding services. Business
demands and technology challenges create the need for migration of applications or databases from one
environment to another, either to improve operational efficiency or to manage risk. We provide custom
application development services.
Testing / QA Services
In software development, validation and verification take up a significant percent of the effort, time and
resources. Testing, as a major component of the development process, must ensure quality and costeffectiveness to provide a good return on investment over the long term. The quality of testing can be
improved by adopting a systematic testing approach, whereas cost-effectiveness can be improved by test
automation and by using offshore services.
Software Re-engineering
Existing software systems need to move with the times too, evolving into state-of-the-art IT solutions that
cater to expanding business needs, while preserving business rules and practices in the current system. The
benefits for companies are two-fold: they can leverage their investments in the current system, as well as
move out of proprietary and outdated technologies.
expert
by Detlef. D. Overbeek
Where to start?
Creates Diagrams
Creates Objects
Figure 1: The icons are a quick way to become acquainted with the program...
NOVEMBER 2011 BLAISE PASCAL MAGAZINE 19
29
Figure 3: Change
the name of the Entity
30
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
31
File 9: You also can zoom to see the total work you have created after a while.
32
COMPONENTS
DEVELOPERS
It was quite a job to create all this. Making dependencies and trying to forecast what we will need in future...
Especially the idea of creating the ability to have some kind of a warehouse: if you want to sell anything you'll have to
register these sales, make invoices, eventually create a table for the web shop and so on... It can become very complex:
don't underestimate the time you will need to do all this;
it's not only the creation but redefining goals for your company, asking specialists to get advice and eventually
changing your opinion which in itself is not very easy.
NOVEMBER 2011 BLAISE PASCAL MAGAZINE 19
COMPONENTS
DEVELOPERS
33
I think it is worthwhile to explain how a structure in itself works and we will show you how the details evolved. We
will do so when we come to the program development details: it is of course not meant to be complete we would
have to write a book about this but some details must be understood before you could start your own shop and
registration. So in figure 11 you can see some details emerging: the Contact table is actually the centre of all other
dependencies. The next is the Company table. As you can see in this figure, the address table is created apart from the
Contacts table because of multiple relationships with Invoices, Warehouse Registratio and so on.
34
COMPONENTS
DEVELOPERS
The Private table keeps the fields for name of the Person, and the Company was chosen to be less important than the
Contact: its a choice you canof course make your own descions. In figure 12 you can see the connections designed for
bookkeeping: Invoices / Correspondence / Articles an orders. Of course this is not the complete information, but you
can get an idea about what complex task it can be to create a simple shop handling some articles, and then try to do
some bookings and orders. In the next article we will dive into the details of how to create a table, make
dependencies and how they sometimes need to be very carefully handled in these very complex relationships.
The Unicode ability of modern tables needs to be explained as well: especially if you want to create a shop
that has an international audience.
NOVEMBER 2011 BLAISE PASCAL MAGAZINE 19
COMPONENTS
DEVELOPERS
35
expert
BeepOnError: boolean
DefaultValue: double
EnforceMinMaxLimits: boolean;
FloatValue: double
FocusColor: TColor
IntegersOnly: boolean
IntegerValue: int64
MaximumValue: double;
MessageOnError: boolean
MinimumValue: double;
TreatEnterAsTab: boolean
COMPONENTS
DEVELOPERS
37
Unit uTestNumberEdit;
{$mode objfpc}{$H+}
Interface
Uses
Classes, SysUtils, FileUtil, Forms, Controls,
Graphics, Dialogs, ExtCtrls, numberedit;
Type
{ TForm1 }
TForm1 = Class(TForm)
Procedure FormCreate(Sender: TObject);
Private
FTestEdit: TNumberEdit;
Public
{ public declarations }
End;
Var Form1: TForm1;
Implementation
{$R *.lfm}
{ TForm1 }
Procedure TForm1.FormCreate(Sender: TObject);
Begin
FTestEdit := TNumberEdit.Create(Self);
FTestEdit.Parent := Self;
FTestEdit.Top := 10;
FTestEdit.Left := 10;
end;
End.
38
COMPONENTS
DEVELOPERS
TCustomNumberEdit = class(TCustomLabeledEdit)
Private
FBeepOnError: boolean;
FDefaultValue: double;
FEnforceMinMaxLimits: boolean;
FFocusColor: TColor;
FIntegersOnly: boolean;
FMaximumValue: double;
FMessageOnError: boolean;
FMinimumValue: double;
FTreatEnterAsTab: boolean;
Function GetFloatValue: double;
Function GetIntegerValue: int64;
Procedure SetFloatValue(AValue: double);
Procedure SetIntegerValue(AValue: int64);
public
property BeepOnError: boolean read FBeepOnError
write FBeepOnError;
property DefaultValue: double read FDefaultValue
write FDefaultValue;
property EnforceMinMaxLimits: boolean
read FEnforceMinMaxLimits
write FEnforceMinMaxLimits;
property FloatValue: double read GetFloatValue
write SetFloatValue;
property FocusColor: TColor read FFocusColor
write FFocusColor;
property IntegersOnly: boolean
read FIntegersOnly write FIntegersOnly;
property IntegerValue: int64
read GetIntegerValue write SetIntegerValue;
property MaximumValue: double read FMaximumValue
write FMaximumValue;
property MessageOnError: boolean
read FMessageOnError write FMessageOnError;
property MinimumValue: double read FMinimumValue
write FMinimumValue;
property TreatEnterAsTab: boolean
read FTreatEnterAsTab write FTreatEnterAsTab;
end;
PerformTab(True);
Exit;
End;
if not (Key in [#8,#9,'+','',DefaultFormatSettings.DecimalSeparator,'0'..'9'])
then begin
ConditionalErrorMsg('The character ''%s''
cannot be part of a number',[Key]);
Key := #0;
End
else
if ValidInContext(Key)
then Inherited KeyPress(Key)
else Key := #0;
End;
COMPONENTS
DEVELOPERS
39
COMPONENTS
DEVELOPERS
stStart
digit
stSign
COMPONENTS
DEVELOPERS
41
LAZARUS
THE COMPLETE GUIDE
Simple Package 35,00
(this excludes shipping costs 17.50)
- Just the book and a Windows installer CD
for Lazarus value 12.50
- 50 additional sample projects
- extra: additional prenstalled component suites
58
COMPONENTS
DEVELOPERS
COMPONENTS
SEPTEMBER
2011 BLAISE PASCAL MAGAZINE
Pag 18
87
DEVELOPERS
COMPONENTS
DEVELOPERS
43
begin
FCurrentTestEdit := FTestEditRadius;
CreateNumEditPropertyAccessComponents(FTestEditRadius);
FCurrentTestEdit := FTestEditArea;
CreateNumEditPropertyAccessComponents(FTestEditArea);
FCurrentTestEdit := FTestEditVolume;
CreateNumEditPropertyAccessComponents(FTestEditVolume);
FCurrentTestEdit := FTestEditRadius;
end;
44
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
Pag 45
+IntToStr(TouchInput[i].y)));
CloseTouchInputHandle((Message.lParam)
inherited;
end;
Manipulating objects
x: Single; y: Single;
translationDeltaX: Single;
translationDeltaY: Single;
scaleDelta: Single;
expansionDelta: Single;
rotationDelta: Single;
cumulativeTranslationX: Single;
cumulativeTranslationY: Single;
cumulativeScale: Single;
cumulativeExpansion: Single;
cumulativeRotation: Single): HRESULT; stdcall;
function ManipulationCompleted(
x: Single; y: Single;
cumulativeTranslationX: Single;
cumulativeTranslationY: Single;
cumulativeScale: Single;
cumulativeExpansion: Single;
cumulativeRotation: Single): HRESULT; stdcall;
end;
46
47
48
that will save and restore the full item's setup and matrices.
This sample code snippet loads the images as a stack.
With the property MultiTouchRegion.OpenStackMode
set to dmGrid, this causes that when the stack is clicked,
the TMultiTouchRegion will automatically open the stack
with animation to show the images in dmGrid mode:
dmRandom:
matrices of items are initialized in a random way by the
MultiTouchRegion as items are added
dmGrid:
matrices are setup in such a way that items are
displayed as a grid using the Cols/Rows properties
dmCascade: matrices are setup in such a way that items
are displayed in cascade style, using
HorizontalSpacing,VerticalSpacing properties
dmPosition:
matrices are setup to display items in a not rotated and
not scaled way at position Item.ItemX, Item.ItemY.
dmMatrices:
items will be displayed with the matrices
configured as is.
dmStacked:
items are displayed in grid mode organized in stacks.
All items with the same Item.StackIndex
property value will be displayed on top of each other
to form a stack.
It is the DisplayMode = dmMatrices that can be used to
persist the last location & manipulation of items.
The TMultiTouchRegion provides the built-in method
Item controls
MultiTouchRegion.SaveToFile() /
MultiTouchRegion.LoadFromFile()
productivity software building blocks
49
MultiTouchRegion.Items[index].MainItem.Controls
[controlindx].Fill
and
MultiTouchRegion.Items[index].MainItem.Controls
[controlindx].FillDown
that is able to
render pages of a PDF file. On the next page is a
screenshot of such TMultiTouchRegion where the
PDFVisualizer renders the cover page of a number of
magazines. Note also the 4 control items (green circular
arrows) at each side of control from where screen rotation
is performed and the control item in the top right corner
to exit the application and the control item in the top left
corner to line up the items in grid mode.
TMultiTouchRegionPDFVisualizer
ctrl :=
MultiTouchRegion1.Items[0].MainItem.Controls.Add;
ctrl.Location := ilTopRight;
ctrl.Width := 16;
ctrl.Height := 16;
ctrl.Fill.Picture.LoadFromFile("cancelpic.png");
ctrl.Visible := false;
end;
TMyVisualizer = class(TMultiTouchRegionVisualizer)
protected
procedure TForm1.MultiTouchRegion1ItemSelectedChanged
procedure LoadImage(APicture: TD2DPicture;
(Sender: TObject; Item: TMultiTouchItem);
D2DItem: TDisplayInfo; AThread: TMultiTouchThread);
begin
end;
Item.MainItem.Controls[0].Visible := Item.Selected;
end;
procedure TForm1.MultiTouchRegion1ItemControlItemClick
(Sender: TObject; ControlItem: TMultiTouchCustomItem;
Item: TMultiTouchItem);
begin
Item.Free;
end;
50
Summary
51
52
COMPONENTS
DEVELOPERS
expert
DELPHI 5 - XE2
http://qc.embarcadero.com/wc/qcmain.aspx?d=100
883 for my bug report about this documentation issue.
TRectangle
frame forms that we'll design shortly. I've saved the project itself as
FrameDemo.dpr by the way. Now, do File | New Other, and in the
Object Repository go to the Delphi Files section, where you won't find
the FireMonkey Frame option (as mentioned in the help). Instead, we can add
a FireMonkey Form (HD or 3D): For our FireMonkey HD example, just
select a new FireMonkey HD Form. Give it the name FrameDemo and
save it in uFrameDemo.pas. To demonstrate that this Form will actually
be treated as a FireMonkey Frame.
Note that the Caption of the new Form can be left unchanged, since it
will not be shown (when using the Form as a Frame). I've changed the
Caption to FrameDemo only for the sake of the screenshots.
On the FrameDemo Form, we can start by placing a TRectangle
component, with the Align property set to alClient. That way, if we
place the FrameDemo as a Frame inside a Container at the main form,
it will completely fill that container (the client area).
On the TRectangle of the FrameDemo, we can place the components
that we would normally use in reusable Frames, like TEdit, TLabel, etc.
COMPONENTS
DEVELOPERS
53
implementation
uses
uFrameDemo;
{$R *.fmx}
procedure TMainForm.FormCreate(Sender: TObject);
var
FrameDemo: TFrameDemo;
begin
FrameDemo := TFrameDemo.Create(Self);
FrameDemo.Rectangle1.Parent := Rectangle1;
end;
Frame as property
54
COMPONENTS
DEVELOPERS
Summary
var
MainForm: TMainForm;
implementation
{$R *.fmx}
procedure TMainForm.FormCreate(Sender: TObject);
begin
FrameDemo := TFrameDemo.Create(Self);
FrameDemo.Rectangle1.Parent := Rectangle1;
FrameDemo2 := TFrameDemo.Create(Self);
FrameDemo2.Rectangle1.Parent := Rectangle2;
end;
COMPONENTS
DEVELOPERS
55
expert
by Cary Jensen
DELPHI 5 - XE2
COMPONENTS
DEVELOPERS
Beyond TDataSet
In addition to the aforementioned features which
TClientDataSet inherits from TDataSet, it also
supports a number of valuable features that are not
available in other TDataSet descendants. For example,
TClientDataSet supports aggregation, and grouping.
An aggregate is a calculation (such as a sum, average, or
count) which can be calculated automatically for record
collections. These collections of records are defined by
groups. A group is a collection of records sharing a
common value on an indexed field. Using groups and
aggregates, you can count the total number of sales to
customers in a particular city, calculate the average salary
of employees by department, or determine which
products generate the most revenue all without using
Using a ClientDataSet
The first area I want to address is navigation in which the code. An example of aggregates can be seen in Figure 1,
where each customer's total sales is calculated
ClientDataSet is similar to functionality found in other
TDataSet descendants. For example, you move to the next automatically using an aggregate. In addition, the
record using the Next method, and move to the last record suppression of repeated values in the CustNo and
CustomerTotal fields is performed using the
by calling Last. You can also call the MoveBy method or
GetGroupState method, which lets you determine where a
set the RecNo property to make another record the
given record lies within a group. Another feature unique to
current record. Bookmarks are also supported, which
ClientDataSets
is the cloned cursor. A cloned cursor
enables you to identify records to which you want to
creates
a
new
reference
to the data and change cache of an
return later.
existing
ClientDataSet.
Importantly,
the original
One navigational feature of a ClientDataSet that deserves
ClientDataSet
and
its
clone
can
differ
in a number of
mention is that it supports bidirectional navigation, which
critical
ways.
For
example,
although
they
reference the
is something that many, but not all, TDataSet descendants
same
memory
store,
a
ClientDataSet
and
its clone can
support. This is particularly important since a
point
to
different
current
records,
employ
different filters,
ClientDataSet can load data from one of these
use
different
ranges,
and
even
have
different
ReadOnly
unidirectional TDataSet descendants, such as a
property
values.
Nonetheless,
when
changes
are
made to
dbExpress SQLDataSet, making it possible to support
bidirectional navigation and grid viewing of data obtained the underlying data store, both a ClientDataSet and its
clone are instantly aware of any changes applied to the
from one of these more limited TDataSets.
data
store.
Speaking of unidirectional TDataSets, these TDataSets
It's
actually
more powerful than it sounds since you can
tend to be readonly. The data in a ClientDataSet, however,
have
many
cloned
cursors on a single data store. In fact,
is always read/write (unless you specifically set its ReadOnly
once
a
ClientDataSet
has been cloned, the clone and the
property to True). As a result, the ClientDataSet again
original
are
equal
in
every
way, with respect to their data
permits you to actually edit data obtained from a
store.
For
example,
the
original
can then be closed and the
unidirectional, readonly TDataSet. (This feature was a primary
clone
will
continue
to
maintain
the
data and change cache.
motivating factor in including ClientDataSets in the Professional
Furthermore,
you
can
have
any
number
of clones of a
version of Delphi, beginning with Delphi 6 and Kylix. This version
single
data
store,
giving
you
the
chance
to
have three, ten,
coincided with the introduction of dbExpress, whose TDataSets are
fifty, or even more current records for that store.
all unidirectional and readonly).
Another significant feature that is unique to
With respect to searching, here again ClientDataSets
ClientDataSets is the nested dataset. A nested dataset is a
support all of the features of the TDataSet interface.
In addition to FindKey and FindNearest (and their GotoKey set of zero or more records, embedded in a single field of
a ClientDataSet's records. For example, you can have a
and GotoNearest counterparts),
NOVEMBER 2011 BLAISE PASCAL MAGAZINE 19
COMPONENTS
DEVELOPERS
57
Figure 2. The Customer ClientDataSet contains a nested dataset field, named OrdersTable.
58
COMPONENTS
DEVELOPERS
COMPONENTS
DEVELOPERS
59
COMPONENTS
DEVELOPERS
Tests done:
10 million records in memory
with multiple fields and indexes...
ESB, SOA,MoM, EAI TOOLS FOR INTELLIGENT SOLUTIONS. kbmMW IS THE PREMIERE N-TIER PRODUCT FOR DELPHI /
C++BUILDER BDS DEVELOPMENT FRAMEWORK FOR WIN 32 / 64, .NET AND LINUX WITH CLIENTS RESIDING ON