Blaise 93 UK
Blaise 93 UK
Blaise 93 UK
ARTICLES
From Your Editor page 4
Cartoon
By Jerry king page 5
Delphi 10.4.2 / new features
By Detlef Overbeek page 7
Max Box RSS Feeds of BBC News
By Max Kleiner page 26
New Number Component inside Delphi 10.4.2
By Detlef Overbeek & Marco Cantu (Embarcadero) page 11
New ControlList Component inside Delphi 10.4.2
By Detlef Overbeek & Marco Cantu (Embarcadero) page 15
How differs the new FastReport VCL 2021.0
from the previous versions? page 32
Fastreport VCL 2021 Working with the ReportDesigner
By Detlef Overbeek page 34
InstallAware
By Detlef Overbeek page 52
What's coming in TMS WEB Core v1.7 Ancona
By Bruno Fierens page 60
Lazarus: Webform inside Lazarus
By Michael van Canneyt page 65
Code Snippets 11
By Detlef Overbeek / project by Michael van Canneyt page 78
Web Service Part 2 Storage
By Danny Wind page 84
ORM in kbmMW #3
Copying a table from one database to another
By Kim Bo Madsen page 97
The Bumble bee page 101
Delphinium
ADVERTISERS
The new LibStick page 6
Super Offer Bundle page 24
Subsription +Lazarus Handbook - hardcover page 25
Fastreport page 31
Delphi 10.4.2 available page 30
Barnsten page 59
Lazarus Handbook - Pocket (softcover) page 76
Lazarus Handbook - Hardcover page 77
Delphi Company page 83
Subscription + Library USB Stick page 96
Componnets4Developers page 102
Pascal is an imperative and procedural programming language, which Niklaus Wirth designed (left below) in 1968–69
and published in 1970, as a small, efficient language intended to encourage good programming practices using
structured programming and data structuring. A derivative known as Object Pascal designed for object-oriented
programming was developed in 1985. The language name was chosen to honour the Mathematician, Inventor of the
first calculator: Blaise Pascal (see top right).
Niklaus Wirth Publisher: PRO PASCAL FOUNDATION in collaboration © Stichting Ondersteuning Programmeertaal Pascal - Netherlands
Blaise Pascal Magazine 93 2021 2
Contributors
Stephen Ball Peter Bijlsma -Editor
http://delphiaball.co.uk peter @ blaisepascal.eu
@DelphiABall
Dmitry Boyarintsev Michaël Van Canneyt, Marco Cantù
dmitry.living @ gmail.com michael @ freepascal.org www.marcocantu.com
marco.cantu @ gmail.com
David Dirkse Benno Evers Bruno Fierens
www.davdata.nl b.evers @ everscustomtechnology.nl www.tmssoftware.com
E-mail: David @ davdata.nl bruno.fierens @ tmssoftware.com
Holger Flick
holger @ flixments.com
Wim Van Ingen Schenau -Editor Peter van der Sman Rik Smit
wisone @ xs4all.nl sman @ prisman.nl rik @ blaisepascal.eu
Editor - in - chief
Detlef D. Overbeek, Netherlands Tel.: Mobile: +31 (0)6 21.23.62.68
News and Press Releases email only to [email protected]
Editors Correctors
Peter Bijlsma, W. (Wim) van Ingen Schenau, Rik Smit Howard Page-Clark, Peter Bijlsma
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 ( 2019 prices ) Internat. Internat.
excl. VAT incl. 9% VAT Shipment
Printed Issue
€ 155,96 € 250 € 80,00
±60 pages
Electronic Download Issue
€ 64,20 € 70
60 pages
Printed Issue inside Holland (Netherlands)
Member and donator of IKIPEDI W A
€ 250,00 € 70,00 Member of the Royal Dutch Library
60 pages
Subscriptions can be taken out online at www.blaisepascal.eu or by written order, or by sending an email to [email protected]
Subscriptions can start at any date. All issues published in the calendar year of the subscription will be sent as well.
Subscriptions run 365 days. Subscriptions will not be prolonged without notice. Receipt of payment will be sent by email.
Subscriptions can be paid by sending the payment to:
ABN AMRO Bank Account no. 44 19 60 863 or by credit card or Paypal
Name: Pro Pascal Foundation-Foundation for Supporting the Pascal Programming Language (Stichting Ondersteuning Programeertaal Pascal)
IBAN: NL82 ABNA 0441960863 BIC ABNANL2A VAT no.: 81 42 54 147 (Stichting Programmeertaal Pascal)
Subscription department
Edelstenenbaan 21 / 3402 XA IJsselstein, The Netherlands
Mobile: + 31 (0) 6 21.23.62.68 [email protected]
Copyright notice
All material published in Blaise Pascal is copyright © SOPP Stichting Ondersteuning Programeertaal Pascal unless otherwise noted and may not be copied, distributed
or republished without written permission. Authors agree that code associated with their articles will be made available to subscribers after publication by placing it
on the website of the PGG for download, and that articles and code will be placed on distributable data storage media. Use of program listings by subscribers for
research and study purposes is allowed, but not for commercial purposes. Commercial use of program listings and code is prohibited without the written permission
of the author.
And now for something completely different - FastReport had also some great news:
as you know the phrase: they created their newest version, to have a
during last month the news accumulated look at that I wrote a starters article.
enormously. This issue has now 102 pages! Blaise Pascal Magazine is going to create -
A new version of Delphi was announced. This with the help of FastReport of course – a book
time with only small news: two new about the use of reporting. We will try to
components and of course a lot of bug fixes. publish that by the end of the year.
Happily Bruno Fierens and his TMS team
created again and again new items for Delphi. For some reason I never took a look at various
He displays his new plans in this issue. install programs: only InnoSetup.
He is the only one that really keeps Delphi InstallAware surprised me very much: you
connected to the Internet, I know there are a need to evaluate and consider that installer
few others but they are not quite so program absolutely. Value for money and for
sophisticated as WEBCore. the Delphi users there is a free version. Jason
I will however investigate those suppliers as Strathmore of InstallAware told me they are
soon as possible, and write about their working on a version for Lazarus, and because
products. It is necessary to overlook the entire of that plan: they are working on a version that
range…I think the Internet is the main future is capable of handling instalments on Linux as
platform. well as macOS - and of course Windows.
Lazarus has some big news: The Lazarus and So all together that is why this issue is over a
Free Pascal foundation had asked Martin Friebe hundred pages.
to create a form that will be able to store a
form inside the IDE which is capable of using a Hope you’ll enjoy it. Let’s have fun
browser (Chromium) where almost all the programming!
browsers are built on (even Microsoft's Edge).
So we hope to achieve that the form will be Detlef
connected to the ObjectInspector and all other
technologies that Pas2JS uses, to make
happen what we want: a form that is actually
the browser it self and has one special ability:
WYSIWYG (What You See Is What You Get),
respond to the debugging necessities,
has an underlying help and code completion
and CSS styles. In this issue Michael van
Canneyt has written an explanation that will
show you for the first time how this can work
and even wrote some code that will show the
result of this. Try it!
Yet there is till a lot to be done!
L I B R A R Y 2 0 2 0
89
90
87
88
86
85 51 52 53
84 50 54
55 49 26 27 28
83 29 25
48 56
81 30 24
82 47 9 10 11 57
12 31
80 46 23 8 1
2 13 32 58
78 22 7 3
79 45 14 33
21 4 59
77 44 6
20 5 15 34
75 60
76 43 19 16 35
18 17 61
73 42 36
74
41 37 62
72 40 39 38
71 69 63
70 67 64
68 66 65
procedure procedure
var var
begin begin
for I := 1 to 9 do for I := 1 to 9 do
begin Prof Dr.Wirth, Creator of Pascal Programming language begin
... ...
end end
end; end;
Prof Dr.Wirth, Creator of Pascal Programming language Blaise Pascal, Mathematician
[email protected] Prof Dr.Wirth, Creator of Pascal Programming language Blaise Pascal, Mathematician
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 8
Delphi 10.4.2 / UPDATE: New Component TNumberBox Page 3/17
starter expert
On these pages we show several aspects of
theproject Marco build:
The TNumberBox On the next pages you see the way of letting
The TNumberBox is a special kind of box that the customer choose from Styles that are
mainly does three things: available.
It can receive Integers
It can receive floats
and currency (can’t we all).
Figure 1: the numberbox in the palette
What makes this component very attractive is
its flexibility: Just enter a simple expression into
it and enter you'll have the answer instantly
actually you could use it as calculator.
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 10
10
Delphi 10.4.2 / UPDATE: New Component TNumberBox Page 5/17
Figure 8: Windows 10
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 12
12
Delphi 10.4.2 / UPDATE: New Component TNumberBox Page 7/17
procedure TNumBoxDemo.ComboBox2Change(Sender: TObject); On the next page the complete code of the
begin onCreate. The inline variables are non of
NumberBox1.AcceptExpressions := True;
NumberBox1.SetFocus;
my taste. This is Pascal. Not C# or whatever.
NumberBox1.Text := ComboBox2.Text; This form of frivolous novelties should not be
end; used. It confuses and in this way it loses the
procedure TNumBoxDemo.Exit1Click(Sender: TObject); the strength of Pascal: clear view and clear
begin structure. Know what is where. The benefit is
Application.Terminate; only a few lines of typing, and actually that
end;
makes you aware of the construction of
Pascal.
procedure TNumBoxDemo.rdoAlignClick(Sender: TObject);
begin
NumberBox1.Alignment := TAlignment(rdoAlign.ItemIndex);
end;
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 13
13
Delphi 10.4.2 / UPDATE: New Component TNumberBox Page 8/17
rdoPlacement.ItemIndex := Ord(NumberBox1.SpinButtonOptions.Placement);
rdoMode.ItemIndex := Ord(NumberBox1.Mode);
rdoAlign.ItemIndex := Ord(NumberBox1.Alignment);
if info.Name.StartsWith('Metro')
or info.Name.StartsWith('Tablet')
or info.Name.StartsWith('Windows')
then
Author := 'Windows';
authors.AddPair(Author, info.Name);
try
TStyleManager.LoadFromFile(fname);
except on EDuplicateStyleException do
end;
end;
end;
authors.Sort;
var authorItem: TMenuItem := nil;
for var i := 0 to pred(authors.Count) do
begin
if not Assigned(authorItem) or (authorItem.Caption <> authors.Names[i]) then
begin
authorItem := TMenuItem.Create(mnuStyle);
authorItem.AutoHotkeys := TMenuItemAutoFlag.maManual;
authorItem.Caption := authors.Names[i];
mnuStyle.Add(authorItem);
end;
var styleItem := TMenuItem.Create(mnuStyle);
styleItem.AutoHotkeys := TMenuItemAutoFlag.maManual;
styleItem.Caption := Authors.ValueFromIndex[i];
styleItem.OnClick := StyleMenuItemClick;
authorItem.Add(styleItem);
end;
end;
THE NEW
TCONTROLLISTBUTTON
COMPONENT
We can't use TSpeedButton
directly on the panel, because
the control doesn’t handle
special interactions like button
changed state.
Figure 13: Overview of the form
At design time, there is special dialog with a For controls, which can have different states,
collection of preset configurations, which we added a special TControlListControl
include adjustment for TControlList class (inherited from TGraphicControl).
properties and control collections with You can create new controls that inherit from
specific properties. You use the arrows at the TControlListControl class and can use
top to pick the core configuration and you can mouse events for their items.
fine tune it with some of the other checkbox This is the approach used by
options at the bottom. The wizard overrides TControlListButton - the analogue of a
the control list setting. TSpeedButton that can be used with
TControlList. This button has 3 styles - push
The item you design is replicated (virtually) for
button, tool button and link.
each of the items requested with the
ItemCount property. The visible
surface of the control generally
allows for a number of items, all
with the same width and height.
The control has 3 different layouts:
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 16
16
Delphi 10.4.2 / UPDATE: New Component TControlList Pag11/17
LIVE BINDING
starter expert
Figure 3: Binding
Components
There is a Binding Components item. If we choose that A new Window pops up: The Editing
frmCtrlListDemo3.Bindinglist . It shows all the links created by binding. See figure 4.
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 18
18
Delphi 10.4.2 / UPDATE: New Component TControlList Pag13/17
LIVE BINDING
Figure 5: Here you get a true overview of what you just added and connected
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 19
19
Delphi 10.4.2 / UPDATE: New Component TControlList Pag14/17
LIVE BINDING
Figure:6
Figure: 7
Figure: 9
Figure: 10
Figure: 8
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 20
20
Figure: 11
Delphi 10.4.2 / UPDATE: New Component TControlList Pag15/17
LIVE BINDING
Blaise
BlaisePascal
PascalMagazine
Magazine93
912021
2021 21
21
Delphi 10.4.2 / UPDATE: New Component TControlList Pag16/17
LIVE BINDING
Figure13:
Figure16:
Figure17:
Figure14:
Figure15: Figure18:
procedure procedure
var var
begin begin
for I := 1 to 9 do for I := 1 to 9 do
begin Prof Dr.Wirth, Creator of Pascal Programming language begin
... ...
end end
end; end;
[email protected]
Prof Dr.Wirth, Creator of Pascal Programming language Blaise Pascal, Mathematician Prof Dr.Wirth, Creator of Pascal Programming language Blaise Pascal, Mathematician
https://www.blaisepascalmagazine.eu
L I B R A R Y 2 0 2 0
90
85
86
87
88
50
89
51 52 53
VIDEO
84 54
49 55
26 27 28
83 25 29
48 56
81 24
10 30
82 47 9 11
31 57
23 8 1 12
80 46
SUPER
2 13 32 58
78 22 7 3
79 45 14 33
21 4 59
77 44 6
5 15 34
OFFER (5)
20 60
75 19 16
76 43 18 17 35
73 61
74 42 36
41 37 62
72
€ 150 ex Vat
40 39 38 Quantum Computing / By Detlef Overbeek
71 69 63 Max Box / Max Kleiner
Fastreport / By Detlef Overbeek
70 67 64 MMX / By Detlef Overbeek and Dennis Zubov
68 66 65 Code Examples / By Detlef Overbeek
New Lazarus PJU Files for Mac By Mattias
Gaertner
free shipping
Installing a package on MacOs
RegEx / By Michael van Canneyt
Sample Project: Lazarus & Delphi Easter
ALL CODE ABOUT THE USE Holidays
Multi Tier a series for the web / By Danny Wind
Chess / By Detlef Overbeek
BLAISE PASCAL MAGAZINE
ALL ISSUES IN ONE FILE
PAGE-CLARK
HANDBOOK
FOR PROGRAMMING WITH FREE PASCAL AND LAZARUS
USING LAZARUS
procedure ;
var
including begin
30 example for i := 1
projects to 9 do
begin
end;
end;
COMPUTER (GRAPHICS)
MATH & GAMES IN
934 PAGES PASCAL
R USOK S
ZADBOARU OK
AL
SC
PA
A
L N AZ BO H
FR
EE
AL
LAZARUS HANDBOOK 1
IT SC
W PA
HA L AND
G EE
IN FR
MM
LAZARUS HANDBOOK 2
H
RA IT
ROG G
W
R
P IN
MM
FO
H FO
R
PR
OGRA
el us
n
va sa eek
ha Ino verb
t,
ey ng
nn dra
Ca Oue
o,
2 Bla
ise
Pa
sca
l
: Micner ef O
tl
ors Gärt De
th ,
Au ttias inig
e
Ma n H
e
Sv
Subscription
Combi(4)
Subscription + Lazarus Handbook
(hardcover)
100
Ex Vat 9%
Including shipment!
BBC News
Sentiment Analysis Page1/4 maXbox
maXbox Because of the nature
Author: Max Kleiner of the text and its categories, the classification
„Yesterday I was clever, we will be doing is a form of sentiment analysis
so I wanted to change the world.
or opinion mining. If the classifier returns pos,
Today I am wise,
so I am changing myself." - Rumi then the text expresses a positive sentiment,
whereas if we get neg, then the text expresses
As you way know, we went through the a negative sentiment.
last magazine report on the BBC News
feed, line by line; now we want to equip and This procedure of discovering and classifying
enlarge these texts with a sentiment analysis opinions expressed in a piece of text (like
comments/feedback text/news feed in our
like the following:
case ) is called the sentiment analysis. The
11: French MP and billionaire Olivier intended output of this analysis would be to
Dassault dies in helicopter crash: determine whether the producers mindset
Sun, 07 Mar 2021 20:04:17 GMT toward a topic, product, headline or service
{"probability": {"neg": etc., is in most cases neutral, positive, or
0.46705201547833042, "neutral": negative.
0.81510771060379195, "pos":
0.53294798452166958}, "label":
Let’s get started with the use of an API:
"neutral"}
Const
URLSentimentAPI2=
So the label shows neutral in the middle of 'http://text-processing.com/
possibilities. The english sentiment uses api/sentiment/';
classifiers trained on both twitter sentiment
as well as movie reviews from the data sets.
The dutch and french sentiment is based on
book reviews.
A 503 Throttled response will be returned if As you may see many of the most commonly
you exceed the daily request limit. Using used words or phrases are insignificant when it
async = false in Open() is not always comes to discerning the meaning of a phrase.
recommended, but for a few small requests For example, in the phrase the movie was
this can be ok. Remember that the script will terrible, the most significant words are movie
NOT continue to execute, until the server and terrible, while the and was are almost
response is ready. If the server is busy or slow, useless. You could get the same meaning if you
the application will hang or stop. took them out, that is, movie terrible or terrible
Anyway we open our XMLhttpObject (which is movie. Either way, the sentiment is the same.
late binding) as not asynchronous, that is to Another approach is to measure the sentiment
say, synchronous because we just post a of face feelings with 3 flavours: Joy, Sadness
single block of data with send(). and Anger or Disbelief, but that’s kind of
research.
29
Advertisement maXbox
Fun maXbox Is An All-In-One Script Engine Application: Powered By Delphi. maXbox is an open source script studio with an Object
Pascal scripting language. According to the developer, “it is an open-source script tool engine, compiler, and source library, all in
one. Use it to design and code your scripts! Pure Code for Object Pascal Scripting. The guiding principles are simplicity and the
reduction of complexity to the max. The app is self-containment “out of the box” with no need for installation or registration.”
https://blogs.embarcadero.com/
fun-maxbox-is-an-all-in-one-script-engine-application-powered-by-delphi/
How differs the new FastReport VCL 2021.0 Page 1 / 20
from the previous versions?
Significantly improved work with images -
as in image editors: Improved transparency support for images inside
- High-quality vector SVG images in reports a report. Now FastReport VCL supports not only
- Improved image transparency in different color mask but also an alpha channel in the
formats report preview, on the printout, and exports
which supports transparent images.
New objects widen the concept of a
"report":
Two-Track Pharmacode for designing and
printing medication and vaccine packages
Report safety and security:
Now reports in PDF are protected with a
digital signature. It guarantees its
uniqueness, allows to clearly establish the
authorship, and protects it from editing.
Your reports now correspond with the
docflow standards.
Resource optimization:
- Page miniatures are formed faster Added experimental picture cache with the
- Less memory required for work ability to generate thumbnails and control
New licensing model: overall image quality. New picture cache saves
Starting March 2021 all FastReport VCL memory usage and GDI descriptors. It loads
editions are subscription-based. It means only one instance of duplicated image (can be
that you will always have an up-to-date turned on with
version as long as your subscription is Report.PictureCacheOptions.CachedImagesBu
valid. ildType=tbtOriginal property).
In detail:
Loading and output images in vector SVG
format through standard “Picture” object (only
for Delphi). Enhance the look of your reports!
Added support of Digital signature in PDF select type of signature (hidden, visible,
export with pfx and p12 certificates support. image), and sign up documents with your
Sign up your PDF documents just in 3 simple certificate.
steps: Add the “Digital signature” object
(TfrxDigitalSignatureView),
START
But to make it even more practical – everyone
wants to use a database- I updated the project
to collaborate with a database: One of the
example databases that come with Delphi:
Employee.
So first let’s find out where that is hiding: Figure 2: The project
c:\ProgramData\Embarcadero\InterBase\g
ds_db\examples\database\employee.gdb Let’s start with the more problematic part of the
So now we found out where the necessary files project: getting the database connected.
are residing we can start Delphi. I have done this We have to do that in Delphi itself – you should
with Delphi 10.4.2 but an older version will not be sure InterBase is running on your computer.
be any problem. (In the next issue I will do the Let’s find out…
same Project In Lazarus). So there is no reason
for you not to try and I must say the price of the 1. DELPHI CONNECTING TO DATABASE
program is very affordable. (See the next page figure 3 of the Data
If you want to know details please go to: Explorer Tab ) Go to the Data Explorer Tab at the
https://www.fast-report.com/en/buy/#!/ right side of your Delphi IDE. Choose “Firedac.”
VCL%20(Embarcadero%20RAD%20Studio|Delp Freedom of choice! Not because you need to, but
hi|C++%20Builder)/FastReport%20VCL/
this is the one I used for this simple trial. You
But for now we need to start Delphi. might also choose for dbExpress where there is
Open the project EmbeddedDesigner. This also a database available. All this explanation is
project will be made available for you with your done to make it understandable for you if you
sources on the website downloads address: have to engage your own database. (See figure 4
https://www.blaisepascalmagazine.eu/ of dbExpress on the next page). There are
your-downloads/ small x-crosses and that means it is not
Figure 1: The project form with components needed connected.
IBTable1
DataSource1
frxDBDaset1
IBDatabase1 IBTable1 DataSource1 frxDBDaset1
Figure 15: Right click on the Employee table and choose Modify
v
INTRODUCTION
y
}
x u
~
Fast Reports Reporting must be Fast! Page 10 / 20
Once you start a new project: Figure 21: The outline of the memo text
File Ú New etc . to be drawn
You can start designing it.
(see the large Figure 18 at the top number
INTRODUCTION v
For this I have prepared a form where you can
see the final coupling to a database.
Let’s describe the necessary steps to make
contact with the database:
Figure 19: Open Report Data and then select the Dataset of your choice
INTRODUCTION
By learning the "hotkeys" and mouse techniques, you can significantly accelerate the work in the
designer in the future.
Let's look at the toolbars. In the designer it is possible to allocate five panels:
u Designer mode panel (object panel);
v The "Standard" toolbar;
w The Text toolbar;
x Rectangle toolbar;
y Alignment toolbar.
The Designer Mode Panel is combined with the Object Panel.
Icon Title Description
Object selection Normal operation mode, where the mouse pointer allows selecting
objects, changing their size, etc.
Hand pointer If you click with the left mouse button, you can drag the report sheet.
Magnifying Glass A single left mouse click zooms in 100%, the right mouse button zooms
out 100%. If you press the left mouse button and drag the
mouse without releasing it, it zooms the selected area.
Text Editor By clicking on the Text object, you can edit its content right on the report
sheet. If you press the left button and drag the mouse without
releasing it, the "Text" object will be created on the selected place and
its editor will start.
Format copying The button becomes active if the "Text” object is selected. If you
press with the left mouse button on the "Text" object, it copies to the
object the formatting that has the previously selected object "Text".
Table 1.3 - Designer Mode Panel
The "Standard" toolbar is placed at the top of the program window (Figure 1.2).
Open report Opens an existing report from a file. The keyboard analogue is Ctrl+O.
Save the report Saves the report as a file. The keyboard analogue is Ctrl+S.
The Text toolbar is also placed by default at the top of the program window,
slightly below the Standard toolbar (Figure 26).
INTRODUCTION
Figure 26 - Toolbar "Text” see item w
The "Text" toolbar has the following icons:
Icon Title
INTRODUCTION Description
No Style Allows you to choose a style. To define the liststyle.
Style of styles, call the menu item "Report|Styles...".
Arial Font Allows you to select a font name from the
drop-down list. Remembers the last five fonts used.
10 Font Size Allows you to select the font size from the drop-down list.
The size can also be entered manually.
Bold Sets/removes font thickening.
Italic Sets/removes the cursive of the font.
Width Alignment Sets the alignment of text evenly across the width.
Lower edge alignment Sets the alignment of text at the bottom edge.
Back Ground Color Selects the font color from the drop-down list.
Line Color Selects the line color from the drop-down list.
1 Line thickness Selects the thickness of the line from the drop-down list.
Icon Description
INTRODUCTION
Show the grid.
Horizontal center.
Centralize vertically.
QUICK START
Running through the Install setup is easy.
Because I wanted to do something useful, I
tried a program example I made earlier and
which could use an update. The ClockAgenda.
The clock for the desktop you can put as a
small app somewhere on your desktop which I
want to give an update in the next issue:
create a colouring menu, add a startup for the
app when windows starts and make it also in
Lazarus, so you can choose what you want: Figure 5: The subtext on the wizard shows the
Windows/Linux or Mac. importantant messages
The code is of course as always free…
Hopefully by that time the new InstallAware Anything you do in this wizzard can also be
abilities will be available… done (or changed) using the IDE visual desginer
(see figure 7, page 4/7) or MSIcodesript editor
The Install-Setup is decorated with all the (see figure 8, page 5/7).
windows that pop up during the process.
You’ll find the extra info under each picture.
The Visual Designer shows at the left a list of Here you see what you could do with the
subjects which show a more detailed plan at Windows registry, if you need a controlled
the The main window in the middle/right installation.
section. Its worth to browse through them. It
will maybe even give you new ideas. I think if
they are capable of doing this for various OS’s
this Installer is a must have.
Deleaker
RemObjects
Enterprise Connectors
DevExpress VCL Controls
TMS Software
Gnostice Document Processing
Steema
FastReport
QuickReport
Woll2Woll
Devart Delphi Access Components
uniGUI
Elevate Software
ImageEN Software
Multilizer
CrossVcl
https://www.barnsten.com/product-category/components/
Infotorial
The new version v1.7 of TMS WEB Core has been in development for about 6 months by
now. Many of its features were already in development in parallel to v1.6. And yes, our team
already
- is working on v1.8! It will not come as a surprise to you that in v1.7 there are new
game changing features in TMS WEB Core also.
Those who have been following the TMS WEB Core development since the first version
TMS WEB Core v1.0 Brescia will know that we name the releases after cities along the
famous historic race “MilleMiglia”. To be more precise, the legendary race of 1955. And as
such, after we visited the city Pesaro with v1.6, for v1.7 we land in Ancona. The historical
meaning of the word “Ancona” is elbow which is commonly associated with the shape of the
coastline. After the 'elbow' Ancona, there are new sights towards the more southern coasts of Italy.
Enough history! Let's bring an overview of what our team has been working on for TMS
WEB Core v1.7 Ancona.
u Components wrapping browser API for local file access
The W3C consortium proposed an API forlocal file access from Web browser applications
and Google Chrome implements it already. Given that Microsoft uses the Google Chromium
engine, it is also available in Microsoft Edge Chromium. With TMS WEB Core, you can take
a head start, explore, and start using this with its three components today:
• TWebLocalTextFile
• TWebLocalBinaryFile
The times that software developers thought you could never use a Web application for
controlling your machine's hardware are officially over. We already introduced support for
Bluetooth with our TWebBluetooth component, and with this release we add two new
components TWebUSBSerial and TWebUSBHID that allow you to write applications
communicating with locally connected USB devices using a serial protocol or the HID
protocol. This opens up a whole new field of applications that can be implemented using Web
technologies.
1. var
2. ms: TMemoryStream;
3. begin
4. ms := TMemoryStream.Create;
5. try
6. await(boolean,ABinaryFile.LoadStream(ms));
7. ms.Position := 0;
8. webmemo2.lines.LoadFromStream(ms);
9. finally
10. ms.Free;
11. end;
12. end;
z Miletus framework
This is probably the biggest feature of TMS WEB Core v1.7! Miletus is a framework for
creating native desktop applications with Web technologies. It permits to create wonderful
and modern user-interfaces using (and in many cases reusing) HTML/CSS templates.
62
Infotorial
Still, it allows to run as a desktop application and to access desktop features normally
reserved for a native desktop app. This includes:
• local file access
• operating system menu
• drag & drop interaction with the operating system
• access to the taskbar
• access to local databases (SQLite, MSSQL, PostgreSQL, mySQL, MS Access)
• so much more...
This first introduction of Miletus in TMS WEB Core offers the capability to create Win32
and Win64 native single EXE file applications with a size below 10MB. And in the near
future, we will add macOS and Linux to that.
Stay tuned for another blog with a more detailed overview of the Miletus features. An
additional benefit of Miletus is that we developed this framework from the ground up as
opposed to a similar framework called Electron that is from a 3rd party. This means that for
the future, we have full control to design any feature set we want for Miletus.
| TWebForm extended
We added more flexibility to the TWebForm. This includes:
• Option to have a close button in the caption
• Property to choose whether a shadow border is used or not
• ElementCaptionClassName property added to allow the use of CSS for the caption
• OnDOMContentLoaded event added, that signals when the browser loaded the entire
DOM content
• OnHashChange event added to handle browser back & forward buttons
° TChromium
The CEF4Delphi project has a package file for
installation in Lazarus (CEF4Delphi_Lazarus). The general interface to the Chromium
The Lazarus OnLine Package manager can be Embedded Framework: It basically
used to install this package. gives you access to the CEF API, and can
You will need to install the DCPCrypt package as be seen as the API for the browser.
° TBufferPanel
well, as the CEF4Delphi_Lazarus package
A panel which can be used by the CEF
depends on this package.
browser to draw on, it provides
double buffering (See the simple OSR
Note that when installing through the Online
(Off Screen Rendering) Browser demo)
Package Manager, you must install from the ° TCefServerComponent
external repository, as shown in figure 1 on A small non-visual component that
page 2. implements a small webserver and
The reason is that the changes needed websocket server.
to run in Lazarus are not yet packaged in the ° TChromiumWindow
zip distributed by the people managing the A TWinControl descendent which can be
Online Package manager. used by the CEF browser to host its
Alternatively, you can also install directly from windows. Normally you will not use this,
the CEF4Delphi sources. you should use TBrowserWindow
Simply clone the official repository using your ° TCEFWindowParent
favourite git client: A TWinControl descendent which can be
https://github.com/salvadordf/CEF4Delphi used by the CEF browser to host its
windows. Normally you will not use this,
The Lazarus package is located in the packages you should use TBrowserWindow
directory. The package is a Lazarus package as ° TCEFLinkedWindowParent
any other and can be installed in the IDE with A TWinControl descendent which can be
the usual ’Use Ú Install’ menu from the used by the CEF browser to host its
package dialog. windows. Normally you will not use this,
The Lazarus IDE will offer to rebuild itself, and if you should use TBrowserWindow
all goes well, 2 extra tabs will appear on the ° TCEFURLRequestClientComponent
component palette, shown in Figure 2 on page a TComponent wrapper around a
2/11 and Figure 3 on page2/11. (See below) TCustomCefUrlrequestClient,
The following components are registered on used to handle request progress.
° TCEFWorkScheduler
the ’Chromium’ tab:
a component that can be used to control
when the browser does work and when it
is idle.
° TBrowserWindow
A control that is essentially a combination
Figure 2: Chromium components - Tab 1
of a TCEFLinkedWindowParent
control and TChromium component.
Usually this will be sufficient for most
applications.
° TOSRBrowserWindow
a control similar to TBrowserWindow that
Figure 3: Chromium components - Tab 2
shows the browser window using OSR
(Off Screen Rendering).
° TCEFSentinel
a control that can be used to check the
status of the CEF browser:
You must be careful when to close the
window, when the window is ready for
you to send commands etc.
The components on the ’Chromium Views The first line tells the browser to close itself.
Framework ’ tab are normally not necessary for The second line checks if the browser window
embedding the browser. They are wrappers was actually closed, and if so, allows the form
around CEF classes which - under normal to be closed.
circumstances - you will not need, but they are But what if the browser form was not yet
provided for completeness. closed ? How to close the form ? Well, the
This might look like a lot of components just to TBrowserWindow window as an
implement a browser, but for simple cases, OnBrowserClosed event that is triggered
only a single component is needed: when the browser form is actually closed.
TBrowserWindow. This visual control has We can use this event to close the main form
a TChromium component built-in and it uses again:
this component to control the browser. procedure TForm1.bwBrowserBrowserClosed(Sender: TObject);
begin
CREATING A SIMPLE BROWSER Close;
end;
To create a simple browser, not much code is
needed. To show this, we create a small demo The effect of these 2 event handlers is the
program. We drop an edit-control along the following sequence of events:
top border of the window (edtAddress), u The user closes the main form.
and a TBrowserWindow control that occupies v The OnCloseQuery event is triggered.
the rest of the window: bwBrowser . It tells the browser window to close.
Next to the address bar, we put a small button If the window is not yet closed, the main
btnGo. In the OnClick handler of the button, form is prohibited from closing.
we place the following code: w When the browser window is closed,
the OnBrowserClosed event is triggered.
bwBrowser.LoadURL(UTF8Decode(edtAddress.Text));
It closes the main form.
x Again the OnCloseQuery event is
The UTF8Decode is needed because the LCL triggered. But this time, the IsClosed will
uses UTF8 for all texts in controls, but the evaluate to True, and the main form is
CEF API expects a WideString (or Unicode
allowed to close.
String) in its APIs.
If this were all there was to it, it would of
course be very simple.
Alas, some more work is needed.
The Chromium browser is a complex piece of
software. To let it work correctly, some
initialization is needed, and when closing
down, also some extra code is needed to make
sure the CEF browser close down properly.
Specifically, you can’t just close the form on
which the browser window is located. In the Additionally, on Windows, some extra code is
OnCloseQuery of the form, you must check needed to handle the use of the menu. The
whether the browser window was actually menu uses a separate modal loop, and this
closed before allowing the form to be closed. must be communicated to the CEF browser.
The following code can be inserted in the form
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); declaration:
begin
With bwBrowser do {$IFDEF WINDOWS}
begin procedure WMEnterMenuLoop(var aMessage: TMessage); message WM_ENTERMENULOOP;
CloseBrowser(True); procedure WMExitMenuLoop(var aMessage: TMessage); message WM_EXITMENULOOP;
CanClose:=IsClosed; {$ENDIF}
end;
end;
initialization
InitCEF;
This means that you must copy the complete
finalization contents of the Resource and Release (about
StopCEF; 1.2 Gb ) to your application directory, and this
end.
for every time you create an application that
Since the initialization section of the main uses CEF.
form is only executed after the LCL was That’s of course not very convenient when
initialized, you’re making various applications.
the CEF library will be initialized only after the A better approach may be to copy the contents
LCL is initialized, and CEF will be stopped
of these 2 directories to a single directory
before the LCL is finalized. Let’s see what (in the above example code this is
happens in more detail during initialization: CEF/current/dist ) and tell CEF4Delphi to use
The first line of the InitCEF routine checks if the libraries and support files in that directory.
the global CEF application exists. That is what these lines in InitCEF do:
If it does, it exits: this ensures that even on
$IFDEF WINDOWS}
Linux, the CEF library is initialized only once.
Dir:='c:\CEF\Current\Dist':
On MacOS, after this, an application delegate {$ELSE}
is created, this is a MacOS-specific routine, Dir:='/opt/CEF/current/dist';
needed to handle communications with CEF. {$ENDIF}
GlobalCEFApp.FrameworkDirPath:=Dir;
The call to CreateGlobalCEFApp creates the GlobalCEFApp.ResourcesDirPath:=Dir;
actual GlobalCEFApp instance, and GlobalCEFApp.LocalesDirPath:=Dir+PathDelim+'locales';
does some configuration.
procedure PumpWork(const aDelayMS : int64); Depending on the configuration this will
begin start a second (sub) process. In the
if (GlobalCEFWorkScheduler <> nil) then
GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS); subprocess the return value of this
end; function is False, in the main process the
procedure CreateGlobalCEFApp; function returns True. The subprocess
begin should stop at once, as actually a new
if GlobalCEFApp <> nil then exit; program is started in the sub process.
GlobalCEFWorkScheduler := TCEFWorkScheduler.Create(nil);
GlobalCEFApp:= TCefApplication.Create; That’s it.
GlobalCEFApp.ExternalMessagePump:= True; Now the program is ready to go. Running
GlobalCEFApp.MultiThreadedMessageLoop:= False; the program will result in something like
GlobalCEFApp.OnScheduleMessagePumpWork:= @PumpWork;
{$IFDEF LINUX}
figure 4 on article page 6/11.
GlobalCEFApp.DisableZygote := True;
{$ENDIF}
end;
If you want to create a GUI using a browser, and you want to distribute an application that can be only
be used to load the files you want, you can register a custom URL scheme.
You can use this to serve a restricted list of files, only files from a ZIP file, or even not to distribute files,
but have all files in resources embedded in the executable.
We’ll demonstrate this by creating an To be able to add this definition, you need to
application that plays the Pacman demo from add the uCEFInterfaces, and
the pas2js demos. uCEFResourceHandler
To do this is not very difficult. We’ll use the first units to the uses clause.
demo and extend it a little. When the This class must be registered with the browser,
GlobalCEFApp application is created in the the CefRegisterSchemeHandlerFactory
CEFControl unit, we add a callback in function from the uCEFMiscFunctions unit
which custom URL schemes can be registered: can be used for this:
GlobalCEFApp.OnRegCustomSchemes:=@CEFRegisterCustomSchemes;
CefRegisterSchemeHandlerFactory('local','',TLocalResourceHandler);
This routine will be called when the browser is Now, when the browser needs to handle a URL
started, and is quite simple. When called, it scheme of ’local’, it will create an instance
gets a reference to a scheme registrar object , of TLocalResourceHandler, and call
which can be used to register a scheme: ProcessRequest, GetResponseHeaders
procedure CEFRegisterCustomSchemes(const registrar: TCefSchemeRegistrarRef); and ReadResponse,
Var aOptions : TCefSchemeOptions; in that order.
begin
aOptions:=CEF_SCHEME_OPTION_STANDARD or CEF_SCHEME_OPTION_LOCAL;
registrar.AddCustomScheme('local', aOptions);
end;
S
ARU
LAZARUS HANDBOOK
S
RU LAZ
AZA ND
LAZARUS HANDBOOK 2
DL L A
AN CA
AL PAS
ASC REE
EP ITHF
FRE
LAZARUS HANDBOOK 1
W
ITH ING
GW MM
MIN ROGRA
AM P
GR FOR
PRO
FOR
+ 9 34
PA
GE
S
INCLUDED:
bookmark - creditcard - usb stick
which contains the personalized pdf
file of the book and the extra program files. So 934 pages
in two books
you have your electronic as wel the printed book
in one product.
R USOK S R USOK S
ZADBOARUOOK ZADBOARUOOK
S
AL AL RU
SC SC ZA
PA PA LA
A
L N AZ B W
IT
H
FR
EE
PA
SC
AL
A
L N AZ B W
IT
H
FR
EE
PA
SC
AL
PAS
CA
LA
ND
HA L AND HA L AND
G EE G EE EE
LAZARUS HANDBOOK
IN FR IN FR
MM H MM H FR
RA IT RA IT TH
OG G
W OG G
W WI
PR IN PR IN G
IN
R MM R MM
FO
H FO
R
PR
OG
RA FO
H FO
R
PR
OG
RA
FO
R
PR
OG
RA
MM
+
u th s G ig, D
A ttia in
Ma n H
Sv
e
e
an
l v ssa ee
ae ou erb
ich r In Ov
: M ne tlef
ors ärt e
k
t,
ey ng
nn dra
Ca Oue
o,
2 Bla
ise
Pa
sca
l
th
Au ttias inig
Ma n H
Sv
e
e
,
an
l v ssa ee
ae ou erb
ich r In Ov
: M ne tlef
ors Gärt De
k
t,
ey ng
nn dra
Ca Oue
o,
2 Bla
ise
Pa
sca
l
4
PA
GE
S
93
HardCover (3)
934 Pages
75 euro ex Vat
including shipment in two books
including. PDF
https://www.blaisepascalmagazine.eu/product-category/books/
INTRODUCTION
Printing is closely related to graphics and
drawing: when you want to print something,
you must draw it on a canvas – in this case a
printer page. Printing is implemented in the
Printer4Lazarus package. (There is a similar-
sounding package called Printers4lazide,
which enables a Print Menu in the IDE itself,
which is not necessary for regular printing
support in a LCL application).
Method Purpose
Abort Stop the current printing job, discarding all pages.
BeginDoc Start a new printing job.
NewPage Starts a new page in the current print job, saving the current page
and increasing PageNumber.
EndDoc Ends the printing job, and sends the job to the printer.
Refresh Refreshes the list of printers and fonts.
SetPrinter Set the current printer.
RestoreDefaultBin Restore the default bin on the printer.
Write Write something directly to the printer
(to be used only in raw printing mode).
The page Orientation (of type PrinterOrientation) can take one of four self-descriptive values:
poPortrait, poLandscape, poReverseLandscape, poReversePortrait.
The PrinterType property (of type TPrinterType) can take one of two self-descriptive values: ptLocal
or ptNetWork.
The PrinterState property can have one of the TPrinterState enumeration values:
psNoDefine, psReady, psPrinting, psStopped. These enumerations are
self-explanatory, except psNoDefine which here means that printer state information is not available.
The TPaperSize class contains information about the currently selected printer paper size.
TPaperSize has the following properties:
Property Type Purpose
DefaultPaperName String The name of default paper size.
DefaultPapers Boolean Is this class using a default list of predefined papers?
Height Integer The paper height in dots.
PaperName String The name of the currently selected paper.
PaperRect TPaperRect A structure describing the (printable and actual)
paper rectangles.
PaperRectOf Array An array of paper rectangles,
indexed by paper name.
SupportedPapers TStrings A list of supported (or predefined) paper sizes.
Width Integer The paper width in dots.
The Lazarus SelectPrinter example demonstrates the use of these dialogs and how they affect the Printer
object. A screenshot of this demo is shown below.
It is important to note that the
coordinate system of the printer
canvas is in dots,
and that the actual size of all things
printed or drawn will depend on the
resolution of the printer. Also note that
the actual printable area is often
smaller than the whole page. Many
laser, inkjet and dot-matrix printers
cannot print across the entire paper
surface. The actually available page
width and height are therefore
important, and the coordinate system
of the page starts at the origin of the
printable area.
This series of articles is about writing your own consumes your web service could be caching
web services server and client in Delphi. The requests. It’s easy to notice when you run into
approach of all articles is pragmatic. The first this.
article introduced some of the concepts you
need to know and shows you how to create and If you get the same result from a GET request,
consume your own web service in Delphi with even if the data in the server has changed, then
just the GET request. This second article shows your web client is caching. Taking a look at
you how to update the data in the web service network traffic helps as well. If the web client
and how to create in-memory storage for the only generates network traffic on the first net
web service. request, you know what’s happening. It’s easy
to prevent this type of caching behaviour, by
In the previous article we only used the HTTP setting the Cache-Control and Expires elements
GET request to return data from our web in the HTTP header. Remember this if you’re not
service. This time we will add the other three getting the new data that you want to get from
HTTP commands to our web service. your GET.
Figure 2:
In the REST Debugger we can see that the returned Content-Type = application/json
and if we open the tab Body we see that the returned JSON is valid.
Figure3: Result
We are now ready to add some new methods to The next step is creating an actual Key Value
our web service. store in-memory to hold the data for this web
service. We will be using a generic TDictionary
OPEN THE WEB SERVER SERVICE to store the Key Value pairs.
(WebServiceServerWithGUI ) we created in the To safely and successfully use this in-memory
previous article in Delphi. It’s compatible with Key Value store we need to know how the
either Delphi 10 Community, Delphi 10 WebModule handles incoming requests. A Web
Professional, Enterprise or up. Broker application has only one WebModule
class variable as you can see in the interface
u In the WebModuleUnit edit the Actions section of the WebModuleUnit
property and add a new handler with name
var
WebActionItemKeyValueGET, MethodType WebModuleClass: TComponentClass = TWebModule1;
mtGet and pathinfo /KeyValue. Figure 4:
w
3. Run the web service again, click the Start
button and start the REST Debugger and
test if your web service still works and a GET
request of this URL yields the expected
valid JSON result.
http://localhost:8080/KeyValue
Figure 5: Response
var WebModuleClass: TComponentClass = TWebModule1; This * makes sure that any URL that
starts with /KeyValue, but continues with
implementation
additional URL segments actually ends
{%CLASSGROUP 'System.Classes.TPersistent'} up in this WebActionItem handler. So
{$R *.dfm} http://localhost:8080/KeyValue/0
uses is now also handled by this action
System.StrUtils, System.Generics.Collections, System.SyncObjs; handler.
var
gLock: TObject;
{ Next we create a function to parse
both the URL query parameters as
gKeyValueStore: TDictionary<string, string>; well as the URL segment
parameters. Add a protected
y
. At the end of the WebModule unit add an function declaration to the
initialization section where you create both WebModule.
the locking object and the Tdictionary. private
initialization { Private declarations }
protected
gLock := TObject.Create; function GetParameters(const aActionPath,
gKeyValueStore := TDictionary<string, string>.Create; aRequestPath: string): TStringDynArray;
gKeyValueStore.AddOrSetValue('0', 'Zero'); public
{ Public declarations }
end. end;
We now have an in-memory Key Value store. To | And write the following code to parse both
retrieve a value in response from a HTTP GET types of parameters from the URI
request we need to do some additional legwork. function TWebModule1.GetParameters(const aActionPath,
aRequestPath: string): TStringDynArray;
var
First we need to parse the parameters in a HTTP lActionPathLength, lRequestPathLength: Integer;
lParameter: string;
request for our resource identifiers. In a HTTP lParameters: TStringDynArray;
request to a REST webservice a parameter is begin
SetLength(Result, 0);
usually sent by using additional URL segments. So lActionPathLength := aActionPath.Length;
to get the Value for Key 0 in the KeyValue resource lRequestPathLength := aRequestPath.Length;
if (lRequestPathLength > lActionPathLength) then
you’d use a URI like this begin
http://localhost:8080/KeyValue/0 lParameter := RightStr(aRequestPath,
lRequestPathLength - lActionPathLength);
For REST web services using URL segments is lParameters := SplitString(lParameter,'/');
the preferred and also the most simple method. if (Length(lParameters) > 0) then
But if you want to you can also support begin
Result := lParameters;
specifying them as URL query parameters, end
starting with the question mark and separated end;
by ampersands. end;
http://localhost:8080/KeyValue?key=0
This second method is already supported in the
TWebRequest with the QueryFields method, but
to support using the preferred URL segment Figure 6: Response
parameters we need to add a bit of
code as well as change the PathInfo
of the Item for the KeyValue GET.
Figure 7: Zero
prefered
Our next major step is to add both a PUT and a POST handler.
When data is sent to a web service, the data can be sent as part of a URL segment like this
http://localhost:8080/KeyValue/1/One but his method has some limitations, one obvious one
being that not all characters are allowed in URL segments as they have a special meaning. If you want
to send larger or more complex items you would use the HTTP requests body. We want to support
both methods of sending data to our web service.
~ Add a PUT handler to the WebModule unit, with method type mtPut.
Figure 8: Actions
if not(lValue.IsEmpty)
then
begin
Response.ContentType := 'application/json; charset=UTF-8';
gKeyValueStore[lKey] := lValue;
Response.Content := ' {"result":[]}';
Handled := True;
end
else
begin
Handled := False;
end;
end
else
begin
{Do not reply}
Handled := False;
end;
end;
At this point you may have already run into a Our last HTTP Command will be the
potential issue we just introduced when DELETE. Just add it to the handlers as
adding the POST method. What happens if you before, this time with mtDELETE.
try to POST a Value for a non-existing key?
You may have noticed that we left out URL query As a teaser we also added a gLock object, but
parameter parsing in the PUT, POST and we did not actually write any code for it. We
DELETE. This was intentional, as using URL will do that in our next article, where we’ll add
segment parameters is the preferred method for some code to make sure any access to our in-
a REST web service. However due to the memory Key Value store is handled in a thread
limitations of URL segment parameters, you safe manner. In that next article we will also
may wish to add URL query parameters for the add error handling and of course expand our
PUT/POST and DELETE as well. This could be Web Service client to consume our web
done quite easily with a duplicate of the sample service. There might even be some JavaScript
code from the GET request handler. code to consume our web service and further
on some additional JSON serialization. Stay
A short recap of the things we have done in this tuned!
article. We created a GET request that correctly
parses both URL query parameters and URL
segment parameters and returns a value from
the in-memory Key Value store. We also created
PUT and POST requests that handle passing
content as part of the URL segment, for short
values, as well as from the HTTP content
stream, for larger more complex values.
L I B R A R Y 2 0 2 0
89
90
87
88
86
85 51 52 53
84 50 54
49 55 26 27 28
83 29 25
48 56
81 30
24
82 47 9 10 11 57
12 31
80 46 23 8 1
2 13 32 58
78 22 7 3
79 45 14 33
21 4 59
77 44 6
20 5 15 34
75 60
76 43 19 16 35
18 17 61
73 42 36
74
41 37 62
72 40 39 38
71 69 63
70 67 64
68 66 65
procedure procedure
var var
begin begin
for I := 1 to 9 do for I := 1 to 9 do
begin Prof Dr.Wirth, Creator of Pascal Programming language begin
... ...
end end
end; end;
Prof Dr.Wirth, Creator of Pascal Programming language Blaise Pascal, Mathematician
[email protected] Prof Dr.Wirth, Creator of Pascal Programming language Blaise Pascal, Mathematician
https://www.blaisepascalmagazine.eu
1 year Subscription+
the new LibStick
(on USB Card - 90 Issues)
70
ex vat / inc. shipment
ORM in kbmMW #3 – Copying a table from one database to another Page 1/4
By Kim Bo Madsen
uses
But what if the table in the database do not exist DB, Math, Classes, System.Generics.Collections,
as a Delphi class? Well the ORM is fortunately kbmMWGlobal, kbmMWObjectMarshal, kbmMWNullable,
kbmMWORM, kbmMWRTTI;
able to create one for us, based on just about
any existing table in any of the supported type
databases. [kbmMW_Table('name:TBLNEWS')]
TTBLNEWS = class
procedure TForm1.CreateDelphiClass(const ATableName:string; const AStrings:TStrings);
var
t:TkbmMWORMTable;
begin
t:=FORMSrc.SurfaceDynamicTable(ATableName,[mwsdtoPromoteFieldDefaultsAsGenerators]);
if t<>nil then
AStrings.Text:=FORMSrc.GenerateDelphiClass(t,[mwocgoNoSchemaNameInClassName]);
end;
private
The above code shows how to easily have the FAUTOINC:integer;
ORM, at runtime, generate the needed Delphi FGROUPNO:kbmMWNullable<integer>;
code that describes a table, and thus can be FARTICLENO:kbmMWNullable<integer>;
FPARENTNO:kbmMWNullable<string>;
used for creating tables in all sorts of ORM FTHREADNO:kbmMWNullable<string>;
connected databases. FCLIENTDATE:TkbmMWDateTime;
FSERVERDATE:TkbmMWDateTime;
FDATESTR:kbmMWNullable<string>;
In the above example, FORMSrc is a FNUMLINES:kbmMWNullable<integer>;
variable/field of type TkbmMWORM, which has FNUMBYTES:kbmMWNullable<integer>;
FCONTENTTYPE:kbmMWNullable<string>;
been connected to a connection pool, that FCANCELLED:word;
represents the database. FMAILFROM:kbmMWNullable<string>;
FFROMADDRESS:kbmMWNullable<string>;
FORMSrc:=TkbmMWORM.Create(cpSrc); FREPLYTONAME:kbmMWNullable<string>;
FREPLYTOADDRESS:kbmMWNullable<string>;
chSrc is the connection pool, defined at FSUBJECT:kbmMWNullable<string>;
designtime, and in this case hooked up to a FMESSAGEID:kbmMWNullable<string>;
FNREFERENCES:kbmMWNullable<string>;
FireDAC database instance connected to an FHEADER:kbmMWNullable<string>;
old Firebird 1.5 database (which happens to FBODY:kbmMWNullable<string>;
be our old newsgroup database). FLASTTHREADPOST:TkbmMWDateTime;
FLASTTHREADPOSTNO:kbmMWNullable<integer>;
FLASTTHREADPOSTFROMNAME:kbmMWNullable<string>;
All we need to do is to ask the ORM to surface FTOTALTHREADPOSTS:kbmMWNullable<integer>;
the table based on the table name, and then FTOTALREPLIES:kbmMWNullable<integer>;
FAPPROVED:word;
produce the class for that table. FIPADDR:kbmMWNullable<string>;
[kbmMW_Field('name:GROUPNO', ftInteger)]
property GROUPNO:kbmMWNullable<integer> read FGROUPNO write FGROUPNO;
[kbmMW_Field('name:ARTICLENO', ftInteger)]
property ARTICLENO:kbmMWNullable<integer> read FARTICLENO write FARTICLENO;
[kbmMW_Field('name:PARENTNO', ftMemo)]
property PARENTNO:kbmMWNullable<string> read FPARENTNO write FPARENTNO;
[kbmMW_Field('name:THREADNO', ftMemo)]
property THREADNO:kbmMWNullable<string> read FTHREADNO write FTHREADNO;
[kbmMW_Field('name:CLIENTDATE', ftDate)]
property CLIENTDATE:TkbmMWDateTime read FCLIENTDATE write FCLIENTDATE;
[kbmMW_Field('name:SERVERDATE', ftDate)]
property SERVERDATE:TkbmMWDateTime read FSERVERDATE write FSERVERDATE;
[kbmMW_Field('name:NUMLINES', ftInteger)]
property NUMLINES:kbmMWNullable<integer> read FNUMLINES write FNUMLINES;
[kbmMW_Field('name:NUMBYTES', ftInteger)]
property NUMBYTES:kbmMWNullable<integer> read FNUMBYTES write FNUMBYTES;
[kbmMW_Field('name:CANCELLED', ftSmallInt)]
[kbmMW_NotNull]
property CANCELLED:word read FCANCELLED write FCANCELLED;
[kbmMW_Field('name:NREFERENCES', ftMemo)]
property NREFERENCES:kbmMWNullable<string> read FNREFERENCES write FNREFERENCES;
[kbmMW_Field('name:HEADER', ftMemo)]
property HEADER:kbmMWNullable<string> read FHEADER write FHEADER;
[kbmMW_Field('name:BODY', ftMemo)]
property BODY:kbmMWNullable<string> read FBODY write FBODY;
[kbmMW_Field('name:LASTTHREADPOST', ftDate)]
property LASTTHREADPOST:TkbmMWDateTime read FLASTTHREADPOST write FLASTTHREADPOST;
[kbmMW_Field('name:LASTTHREADPOSTNO', ftInteger)]
property LASTTHREADPOSTNO:kbmMWNullable<integer> read FLASTTHREADPOSTNO write FLASTTHREADPOSTNO;
[kbmMW_Field('name:TOTALTHREADPOSTS', ftInteger)]
property TOTALTHREADPOSTS:kbmMWNullable<integer> read FTOTALTHREADPOSTS write FTOTALTHREADPOSTS;
[kbmMW_Field('name:TOTALREPLIES', ftInteger)]
property TOTALREPLIES:kbmMWNullable<integer> read FTOTALREPLIES write FTOTALREPLIES;
[kbmMW_Field('name:APPROVED', ftSmallInt)]
[kbmMW_NotNull]
property APPROVED:word read FAPPROVED write FAPPROVED;
end;
implementation
initialization
TkbmMWRTTI.EnableRTTI([TTBLNEWS, TObjectList<TTBLNEWS>]);
kbmMWRegisterKnownClasses([TTBLNEWS, TObjectList<TTBLNEWS>]);
COMPONENTS
DEVELOPERS 4 DX
EESB, SOA,MoM, EAI TOOLS FOR INTELLIGENT SOLUTIONS. kbmMW IS THE PREMIERE N-TIER PRODUCT FOR DELPHI / C++BUILDER