You are on page 1of 40

D E L P H I,

L A Z A R U S,
O X Y G E N E,
S M A R T M O B I L E,
A N D
P A S C AL
R E L A T E D
L A N G U A G E S
A N D R O I D,
I O S,
M A C,
W I N D O W S
&
L I N U X

BLAISE PASCAL MAGAZINE 49

I
LA S

PA

L MAGAZINE
SCA
EDITORS CHOICE
1st PRIZE
AWARD WINNER

2015

ENCRYPTION IN PRACTICE - BY ANDREA RAIMONDI


THALES OF MILETUS - A PRE-SOCRATIC GREEK PHILOSOPHER - BY EDITOR

FOR

Fast Reports

MAPPING USING DELPHI - BY PETER VAN DER SMAN


KWANTUM COMPUTIN
G - BY
ED
OR
Reporting
must
beI T
Fast!
FAST REPOR
T S V C L ( 4 DELPHI
) I N A NTO
U T DELPHI
SHELL Y J O H NPASCAL
KUIPER
OVERVIEW
/B
BLAISE
START WITH ARDUINO PROGRAMMING V3.1 - BY MAX KLEINER

(HISTORY)
DRAG AND DROP EXPLAINED
LAZARUS
A R D U I N OFOR
: T HYOU
E V IFOR
SUIN
O P R O J EAND
C T - DELPHI
PART 2
C O L L E C T D A T A A N D W OBY
R KMICHAEL
W I T H I VAN
T I NCANNEYT
DELPHI
B Y B O IPACKAGE
AN MITOV
THE TMS LCL HW PACK FOR RASPBERRY PI OPEN-SOURCE
LOG, DEBUG AND AUDIT T
HE
KBMM
W WAY
BY
BRUNO
FIERENS
KIM MADSEN
TFRAMESTAND VERSION 1.1 RELEASED:B Y
WHAT'S
NEW!
BY ANDREA MAGNI
THE QUEENS PUZZLE PROGRAMMING DESCRIPTION
BY DAVID DIRKSE
INTERNET OF THINGS WITH ESP8266 AND VISUINO
BY BOIAN MITOV

DOWNLOAD ISSUE PRICE 5,00


IN
ISS
PR
IC
1 ,00. 0
00
PP
RR
IN
TT
EE
DDI S
UU
E EP R
IC
E E 1 5
LO
ISS
PR
IC
00
DD
OO
WW
NN
LO
AA
DDI S
UU
E EP R
IC
E E 5 ,50. 0

BLAISE PASCAL MAGAZINE 49


D E L P H I,
L A Z A R U S, S M A R T M O B I L
A N D
P A S C A L
R E L A T E D
L
A
N
F O R
A N D R O I D,
I O S, M A C,
W I N D O W S

E
S T U D
G
U
A
G
& L I N U X

I
E

O,
S

CONTENTS NR1 2016


ARTICLES
OVERVIEW DELPHI TO DELPHI / BLAISE PASCAL
(HISTORY) PAGE 4 /5
DRAG AND DROP EXPLAINED FOR YOU FOR LAZARUS AND DELPHI
BY MICHAEL VAN CANNEYT PAGE 9
THE TMS LCL HW PACK FOR RASPBERRY PI OPEN-SOURCE PACKAGE
BY BRUNO FIERENS PAGE 31
TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW!
BY ANDREA MAGNI PAGE 6
THE QUEENS PUZZLE PROGRAMMING DESCRIPTION
BY DAVID DIRKSE PAGE 37
INTERNET OF THINGS WITH ESP8266 AND VISUINO
BY BOIAN MITOV PAGE 15

tmssoftware.com
productivity software buiding blocks

I
LA S

A G A Z I NE
CA L M
S
A

B
FOR

EDITORS CHOICE
1st PRIZE
AWARD WINNER

2015

Fast Reports
Reporting must be Fast!

Advertisers
Barnsten PAGE 30
COMPONENTS 4 DEVELOPERS PAGE 40
FASTREPORT PAGE 14
UPSCENE PAGE 36
MITOV SOFTWARE PAGE 28

Publisher: Foundation for Supporting the Pascal Programming Language


in collaboration with the Dutch Pascal User Group (Pascal Gebruikers Groep)
Stichting Ondersteuning Programmeertaal Pascal

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

Stephen Ball
http://delphiaball.co.uk
@DelphiABall

Peter Bijlsma -Editor


peter @ blaisepascal.eu

Dmitry Boyarintsev
dmitry.living @ gmail.com

Michal Van Canneyt,


michael @ freepascal.org

Marco Cant
www.marcocantu.com
marco.cantu @ gmail.com

David Dirkse
www.davdata.nl
E-mail: David @ davdata.nl

Benno Evers
b.evers
@ everscustomtechnology.nl

Bruno Fierens
www.tmssoftware.com
bruno.fierens @ tmssoftware.com

Primo Gabrijeli
www.
primoz @ gabrijelcic.org

Fikret Hasovic
fhasovic @ yahoo.com

Cary Jensen
www.jensendatasystems.com
http://caryjensen.blogspot.nl

Max Kleiner
www.softwareschule.ch
max @ kleiner.com

John Kuiper
john_kuiper @ kpnmail.nl

Wagner R. Landgraf
wagner @ tmssoftware.com

Kim Madsen
www.component4developers

Andrea Magni
www.andreamagni.eu
andrea.magni@gmail.com
www.andreamagni.eu/wp

Boian Mitov
mitov@mitov.com

Detlef Overbeek - Editor in Chief


www.blaisepascal.eu
editor @ blaisepascal.eu

Howard Page Clark


hdpc @ talktalk.net

Andrea Raimondi
andrea.raimondi @ gmail.com

Wim Van Ingen Schenau -Editor


wisone @ xs4all.nl

Peter van der Sman


sman @ prisman.nl

Rik Smit
rik @ blaisepascal.eu

Bob Swart
www.eBob42.com
Bob @ eBob42.com

B.J. Rao
contact@intricad.com

Daniele Teti
www.danieleteti.it
d.teti @ bittime.it

Anton Vogelaar
ajv @ vogelaar-electronics.com

Siegfried Zuhr
siegfried @ zuhr.nl

Authors - Christian name in alphabethical order


A
B
C
D
F
G
H
J

Andrea Raimondi ,
Stephen Ball, Peter Bijlsma, Dmitry Boyarintsev
Michal Van Canneyt, Marco Cant,
David Dirkse, Daniele Teti
Bruno Fierens
Primo Gabrijeli, Mattias Gaertner
Fikret Hasovic
Cary Jensen

Jeremy North

jeremy.north @ gmail.com

L
K
M
N
O
P
S
Z

Wagner R. Landgraf, Sergey Lyubeznyy


Max Kleiner
Kim Madsen, Felipe Monteiro de Cavalho
Jeremy North,
Inoussa Ouedraogo
Howard Page-Clark,
Rik Smit, Bob Swart,
Siegfried Zuhr

Editor - in - chief
Detlef D. Overbeek, Netherlands Tel.: +31 (0)30 890.66.44 / Mobile: +31 (0)6 21.23.62.68
News and Press Releases email only to editor@blaisepascal.eu
Editors
Peter Bijlsma, W. (Wim) van Ingen Schenau, Rik Smit,
Correctors
Howard Page-Clark, James D. Duff
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 ( 2013 prices )
1: Printed version: subscription 80.-- Incl. VAT 6 % (including code, programs and printed magazine,
10 issues per year excluding postage).
2: Electronic - non printed subscription 50.-- Incl. VAT 21% (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
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: 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 / Tel.: + 31 (0) 30 890.66.44 / Mobile: + 31 (0) 6 21.23.62.68
office@blaisepascal.eu

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.

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

OVERVIEW OF DELPHI TO DELPHI HISTORY

DELPHI XE8

On February 8, 2006 Borland announced that it was


looking for a buyer for its IDE and database line of products,
including Delphi, to concentrate on its ALM line. On November
14, 2006 Borland transferred the development tools group to
an independent subsidiary company named CodeGear,
instead of selling it. Borland sold CodeGear to Embarcadero
Technologies in 2008. Embarcadero retained the CodeGear
division created by Borland to identify its tool and database
offerings, but identified its own database tools under the
DatabaseGear name.

Embarcadero Technologies in 2008.


Codegear Delphi 2007.
DELPHI 7 released in August 2002

DELPHI
released February 14, 1995

The roots of Turbo Pascal v1.0 started in Denmark. The first step,
in 1981, was the Blue Label Software Pascal Compiler - BLS Pascal
Compiler v1.2, copyright 1981 by Poly-Data microcenter ApS,
Strandboulvarden 63, DK 2100 Copenhagen - written by Anders
Hejlsberg for the NASCOM kit computer.

Turbo Pascal
Developer(s) Anders Hejlsberg while
working at Borland
Operating system CP/M, CP/M-86, DOS,
Windows 3.x, Macintosh
Platform 8080/Z80, 8085, x86

Lisa - Pascal

was a Pascal implementation for the Apple Lisa workstation.


It was an extension of the earlier Apple Pascal for Apple II machines,
but generated object code for 68000 processors that had to be linked
against the required libraries in the Lisa OS workshop.
Lisa Pascal laid the foundation for the development of Clascal and Mac Pascal
the first implementations of Object Pascal.

Windows

Charles Babbage - mathematician

Niklaus Wirth

conceived of the first programmable computer in the 1830s

born February 15, 1934 He is a Swiss


computer scientist, best known for
designing several programming languages,
including Pascal, and for pioneering several
classic topics in software engineering.

Babbage never built his Difference Engine


- a mechanical calculator with thousands of parts because of cost overruns and political disagreements,
but the inventor passed on plans for its completion,
and in 1991, the Science Museum in London actually
built it (the printing component was finished in 2000).
As suspected, it actually works.

Blaise Pascal (19 June 1623 19 August 1662)


was a French mathematician,
physicist, inventor, writer and Christian philosopher.
creates the first calculators

Discovery of America by Columbus


Columbus led his three ships - the Nina,
the Pinta and the Santa Maria out of the Spanish port of Palos on August 3, 1492.
Discovery of Amerca by the Vikings 990 - 1050
Building of Spain 912 and Portugal 800
Building of France 5852 BC

Decay of the Roman Empire 500


Building of Europe

Archimedes

Mathematician
Archimedes of Syracuse was an Ancient
Greek mathematician, physicist, engineer,
inventor, and astronomer.
He is regarded as one of the leading scientists
in classical antiquity. Wikipedia
Born: 287 - 212 BC, Syracuse, Italy

Roman Empire 700 BC

Plato in Classical Attic;


428/427 or 424/423 348/347 BC)
was a philosopher, as well as mathematician,
in Classical Greece.
Euclid Mathematician
Born Mid-4th century BC - 3rd century BC
Residence Alexandria, Hellenistic Egypt
Fields Mathematics Known for
Euclidean geometry / Euclid's Elements
Euclidean algorithm
Pythagoras Philosopher
Pythagoras of Samos was an
Ionian Greek philosopher, mathematician,
and founder of the religious movement
called Pythagoreanism.
Born: 571 - 495 BC,
Thales Philosopher
Thales of Miletus was a pre-Socratic Greek philosopher
from Miletus in Asia Minor and one of the
Seven Sages of Greece. Many, most notably Aristotle,
regard him as the first philosopher in the Greek tradition.
Born: 624 BC - 546
DELPHI
The cult of Apollo at
Delphi probably
dates back to
the 700s B . C .,

Difference Engine No. 1, portion,1832

ISSUE 40

Page 9
WATER CLOCK - CHINA - BEGINNING OF TIME (BC 4000)
Some authors claim that water clocks appeared in China
as early as 4000 BC

Babbage Difference Engine No. 2

BLAISE PASCAL WAS THE INVENTOR OF THE


MECHANICAL CALCULATOR IN 1642 334 YEARS AGO
BLAISE PASCAL (19 June 1623 19 August 1662) was a
French mathematician, physicist, inventor, writer and
Christian philosopher. He was a child prodigy who was
educated by his father. On 23 November 1654, between
10:30 and 12:30 at night, Pascal had an intense religious
vision and immediately recorded the experience in a brief
note to himself which began:
"Fire. God of Abraham,
God of Isaac, God of Jacob,
not of the philosophers and the
scholars..." and concluded by
quoting Psalm 119:16: "I will
not forget thy word. Amen."
He seems to have carefully
sewn this document into his
coat and always transferred it
when he changed clothes.
Following this experience,
he began writing influential
works on philosophy and
theology. His two most famous
works date from this period:
the Lettres provinciales and the
Penses. Pascal had poor health,
especially after his 18th year, and his death came just two
months after his 39th birthday.

As Chateaubriand described in his The Genius of


Christianity the fascinating author of Lettres un
provincial and Penses. No wonder Jacques Attali,
former student of the Ecole Polytechnique and the
Ecole Nationale d'Administration, writer and
dramatist, economist and convinced believer with
strong interest in the life and work of Pascal has
rediscovered. In the biography, he not only describes
the tragic fate of a child prodigy, an indisputable
genius. The man who was thrown back and forth
between his love for the truth and his religion, but
also dominated the history of half a century in which
France intellectual area ruled the world.

Models of pipes to test the vacuous

There once was a man who, when he was twelve,


with sticks and circles created the mathematics,
which, when he was sixteen, the cleverest treatise on
conic wrote since Antiquity, who, when he was
nineteen, a theoretical knowledge applied in a
machine, which, when he was twenty-three,
formulated the theory of air pressure and thus wiped
one of the great mistakes of the old physics of the
table. And this at an age when other people are barely
aware of their existence, had gone through the whole
cycle of human sciences, realized how insignificant
they were, and pointed to the religion, which, from
that moment until his death at age thirty-nine, despite
illness and pain, languages of Bossuet and Racine
provided, which could write exceptionally funny but
also could argue quite firm, and whom, finally, during
the short period between his illnesses in, by
abstraction, one of the biggest problems in
mathematics managed to solve and wrote down
thoughts about God and man. That 'frightening'
genius named Blaise Pascal. "

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

Blaise Pascal was the inventor of the


mechanical calculator in the early 17th
century.
Pascal designed the machine in 1642. He was spurred
to it when participating in the burden of arithmetical
labor involved in his father's official work as
supervisor of taxes at Rouen. First called the
Arithmetic Machine, Pascal's Calculator and later
Pascaline, his invention was primarily intended as an
adding machine which could add and subtract two
numbers directly although its description could be
extended to a "mechanical calculator with which it was
possible to multiply and divide by repetition." Pascal
went through 50 prototypes before presenting his first
machine to the public in 1645. He dedicated it to Pierre
Sguier, the chancellor of France at the time. He built
around twenty more machines during the next decade,
often improving on his original design. Nine machines
have survived the centuries, most of them being on
display in European museums. In 1649 a royal
privilege, signed by Louis XIV of France, gave him the
exclusivity of the design and manufacturing of
calculating machines in France.

TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW! PAGE 1/3


BY ANDREA MAGNI
starter

expert

Delphi

INTRODUCTION
In a previous article, published within issue 4546, I have covered the basic functionalities of
TFrameStand, a FMX component to ease the use
of TFrame(s) in FMX applications. Since then I've
added a few significant features and this article
will cover them.
Before proceeding, I wanted to leave you a link (
https://youtu.be/Z6_ZvnCmFCw ) with the replay
of my TFrameStand session on CodeRage X, the
online Embarcadero conference held on October,
2015. It is a 50 minutes session covering all the
basic functionalities of the component. Another
resource (italian only) covering the aim and the
basics of TFrameStand is an audio interview I
released to delphipodcast.com (by Marco
Breveglieri) website (
http://www.delphipodcast.com/episode/6/massi
mizzare-user-experience-con-tframestand ).

THE COMPONENT EDITOR

A good design-time support is a great addition


to every Delphi component. It can save a lot of
time (thus improving developer's productivity) and
make easy some tasks for the developer.
The TFrameStand component lets you
combine a stand (defined and stored in a
TStyleBook) with a TFrame instance.
You may want to add here and there animations
while showing and/or hiding the framestand
and it quickly becomes not so trivial to guess
how the final result will look at runtime, since
you cannot run animations in the designer.
Thanks to Delphi's IDE, design-time editors for
the stand (the Style Designer) and the TFrame
(the Form Designer) are available but what you
really need is a way to easily test the stand's
final behavior, without having to compile and
run the application each time you change
something.

AVAILABILITY THROUGH GETIT

This is not properly a new feature but a


really nice news: TFrameStand is
now available through GetIt
(Embarcadero's integrated Package
Manager)! This means that adding
TFrameStand to your IDE now
only takes a 2-click install process.
Simply look for TFrameStand in
GetIt (IDE Tools Get It Package
Manager ) and click Install, accept the
license agreement and confirm:
done!
The component will be immediately
available in your component palette
and properly configured.

The current release (both on GetIt and GitHub) is v.1.1.

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW! PAGE 2/3


AUTOMATIC HIDE DELAY SUPPORT

Still talking about Hide transitions,


another common problem was that you
had to specify (in an argument of the Hide
method) how long the component should
wait between the Hide call and the actual
hiding of the framestand. This amount of
time was needed to accomplish the hide
transition (if there were animations tied to
the Hide transition, of course) before
making the components invisible (and
possibly, free them).
This sounded a bit annoying to me
because it would tie the code (the Hide
call) to the needs of a specific stand.
If you switched the stand, you would
have to change the code.
This is where the TFrameStand's component
editor can help you. In fact, strictly speaking,
at the moment it is more a previewer than a real
component editor. Simply double-click on a
TFrameStand instance at design-time and
you will get a form on the screen, where you
can select one of the stands you have defined (if
any), tune some parameters (like the size of the
frame and its Align property) and test the Show
and Hide actions.
Obviously there is no easy way to preview one
of your actual TFrame instances, so a
placeholder frame is provided (just to give an
idea of where the actual frame will be at runtime).
The testbed area provided in the preview form
can represent your main form or any parent
object you may want to show the framestand
in. Consider checking the value of the
TestBed.ClipChildren property in order
to properly tune your preview.
BETTER HIDE MANAGEMENT
One of the key features (especially on mobile side)
of the component is the ability to add
transitions (animations) in the show/hide
phases.
There was a problem with v.1.0 because you
could call the Hide method of framestand
multiple times resulting in a continuous reset
of the transition (and if you do this in an event
handler that is called very often, the result is very
annoying).
Thus, now the component is aware of its state
(if there is already a runing transition or not) and
the problem is solved. You can still call
multiple times the Hide method but the result
will be fine.

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

Now, v.1.1 solves this by inspecting the stand


(and the frame also) and automatically it
determinates how long the Hide animations
(if any) will take to finish. So you can simply
omit the Delay argument of the Hide call and
let TFrameStand use a proper value instead.
TACTIONLIST COMMON ACTIONS
SUPPORT
The concept of CommonActions has been
extended and now it is possible to link a
TActionList and use it as a repository for
CommonActions. This means that you can bind
any action-enabled control to a specific Action
through TFrameStand.
The Action is selected among those in the
bound TActionList through a (tunable)
naming convention based approach.
Some benefits of this approach are that you can
use standard TAction mechanisms (such as
OnUpdate events) and that it is now easier than
ever to keep presentation code apart from
application code.
The typical scenario for a standard mobile
application, can be described like this: a main
form, a main datamodule, some frames.
Put a TFrameStand and a TActionList
on the datamodule and link them together.
Implement some actions in the TActionList
and then use the new TFrameStand
functionality to bind the actions all over your
stands and frames.
This should help you in keeping your
application code in the datamodule (that can act
as the state holder of your application) and
nowhere else, while letting you to bind actions
wherever you needed.

TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW! PAGE 3/3

DEFAULT PARENT PROPERTY

The last small improvement I added to the


component is a new property to let you set the
default parent object for the framestands.
In v.1.0, if you did not specify a parent in the
Show/Use methods, the form owning
TFrameStand instance was used.
Now, you can set (at design-time) the control to
be used as a parent, where not differently
specified.

About the author


Andrea Magni (http://www.andreamagni.eu) is
an italian computer engineer.
He is 33 years old and lives near Monza (Milan area)
with his wife Marta and his daughter Federica.
Andrea is an experienced Delphi developer (using
Delphi since version 2) who had the luck to work
many years with the best Delphi experts in Italy and
has collected experiences on (very) different
projects during his activity as a freelance software
developer (15 years and counting). Andrea has
joined the Embarcadero MVP program since 2014.
He also has expertise with web and mobile
technologies and embedded systems.

CONCLUSION
This article illustrates the major improvements
introduced with v.1.1 of TFrameStand project.
Many developers are currently using this
component (mostly in mobile applications) and I
have received a good feedback both from the public
presentations (live and online) I did and via
personal e-mail messages.
I am also very happy some people are starting to
contribute (providing bugfixes), keep doing it! I
already have a couple of additions to implement in
the next version and a couple of new demos are
coming soon. So stay tuned and follow my blog (
tag TFrameStand:
http://www.andreamagni.eu/wp/tag/
tframestand/ ) for the latest news!
Andrea Magni
Web: www.andreamagni.eu
Blog: www.andreamagni.eu/wp
Twitter: @andreamagni82

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 1/5
BY MICHAL VAN CANNEYT
starter

expert

ABSTRACT
In this article we show how to implement drag
and drop operations in your application.
INTRODUCTION
Drag and Drop is a common operation in a wellthought of GUI. It makes life for the user easier. It
is therefore good to have some knowledge on how
to implement drag and drop for simple (or less
simple) cases. In this article, we'll look at 2 types
of Drag&Drop:
1.Files dragged onto your application from a
file manager program (such as file explorer on
windows): The expectation of the user is then
that the application will open the files if it
supports the file format.

procedure TMainForm.HandleDrops(
var Msg: tagMSG; var Handled: Boolean)
begin
end;

The second method is to drop a


TApplicationEvents component on the form,
and to assign its OnMessage event handler (It
has the same signature as the above
HandleDrops procedure).
In the HandleDrops message handler, the
actual file drop handling must be done. The file
drop message can be processed with the
DragQueryFile call. This call looks as follows:
function DragQueryFile(Drop: HDROP;
FileIndex: UINT;
FileName: LPWSTR;
cb: UINT): UINT; stdcall;

2.Drag and drop between visual elements


(controls) in an application. For instance, the
user drags selected text to another location; Or
drags items from one list to another list. Both
kinds of drag&drop must be explicitly enabled and
programmed, and they are handled in a
completely different way.
Drag and drop is implemented in the same way in
Lazarus and Delphi for the second case (drag and
drop within an application), but for the first case,
the mechanisms are different.

Drag and drop of files in Delphi


In Deplhi, Drag&Drop of files must be
implemented manually.
In the OnCreate event (or OnShow), the
DragAcceptFiles call from the WinAPI.ShellAPI
unit must be called to notify Windows that the
form accepts files. This call looks as follows:
procedure DragAcceptFiles (Wnd : HWND ;
Accept : BOOL ); stdcall ;

The following code will then enable dropping of


files on a form:
procedure TMainForm .FormCreate (Sender : TObject );
begin
DragAcceptFiles(Handle,True);
end;

To actually accept the files, the WM_DROPFILES


message that is sent to the application handle
must be handled. There are 2 possible options.
The first is to assign the Application.OnMessage
handler in the OnCreate event handler of the form:
procedure TMainForm.FormCreate(Sender: TObject);
begin
DragAcceptFiles(Handle,True);
Application.OnMessage:=HandleDrops
end;

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

It serves 2 purposes:
1. Retrieve the number of files that was
dropped (FileIndex equals $FFFFFFFF).
2. Retrieve the filenames of each of the files:
FileIndex (>0) indicates the index of the file.
The name of the file will be placed in a buffer,
whose size must be reported in cb.
Once the files were accepted, windows must be
notified that the drop is completed, this
happens with the DragFinish routine:
Procedure DragFinish(Drop: HDROP); stdcall;

Both calls accept as the first parameter a handle


to a drag&drop structure. The Drag&Drop
structure handle is passed in the windows
message WParam field.
The following implementation will retrieve all
files, and calls a NewEditor routine for each
dropped file. This could be used in for example
a small text editor application which - like so
many editors - displays each file in a memo on
a tab page:
procedure TMainForm.HandleDrops(var Msg: tagMSG;
var Handled: Boolean);
Var NrFiles,I : Integer; Buffer : Array[0..255] of Char;
begin
Handled:=Msg.Message=WM_DROPFILES;
if not Handled then
exit;NrFiles:=
DragQueryFile(Msg.Wparam,$FFFFFFFF,Buffer,256);
For I:=0 to NrFiles-1 do
begin
DragQueryFile(Msg.Wparam,I,Buffer,256);
NewEditor(StrPas(Buffer));
end;
DragFinish (Msg.WParam);
end;

STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 2/5

Figure 1: File drag and drop in action

The end result of this code can be viewed in


figure 1 on on this page
3 DRAG AND DROP OF FILES IN LAZARUS

Handling drag and drop of files in Lazarus is


quite easy. One property, and one event
handler of TForm are involved:
AllowDropFiles when this property is set to
True, it enables files to be dropped on the
form. (When dragging files, the cursor will
change shape to indicate this).
OnDropFiles This event is invoked when files
have been dropped on the form. The event
will not be invoked when AllowDropFiles is
set to False when created by the IDE, the event
handler looks as follows:
procedure TMainForm.FormDropFiles(Sender: TObject;
const FileNames: array of String);
begin
end;

The FileNames parameter is an array of


strings, which contains the full pathnames of
all the files that were dropped on the form.
What is to be done with the dropped filenames
depends on the application. Typically, it will
open the file and display the contents.
If we repeat the idea of a small text editor
application which - like so many editors displays each file in a memo on a tab page,
then the following code will open the file and
edit it:
10

procedure TMainForm.FormDropFiles(Sender: TObject;


const FileNames: array of String);
Var I : Integer;
begin
// High(FileNames) is the last element in an open array
For I:=0 to High(FileNames) do
begin
NewEditor(FileNames[i]);
end;
end;

In the above code, the FileNames array is


traversed, and for each file, a new editor is
opened. That is all there is to drag&drop of files. In
a real-world application, probably the extension of
the file would be examined to see if it is a
supported file format.
4 SIMPLE DRAG AND DROP WITHIN
AN APPLICATION
To support drag and drop within an
application requires somewhat more properties
than file drag and drop. These properties must
be set on all the controls that are involved in the
drag an drop operation(s).
DragMode

This controls how a drag&drop operation is


started: When set to dmAutomatic, then a
drag&drop is started as soon as the user drags
the mouse over the control. If it is set to
dmManual, then a drag&drop operation
must be started with the StartDrag method.
This can be needed for instance to mark the
difference between a drag&drop and a docking
operation.

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 3/5
The same code can be used for the LBRight
listbox. When the user relased the mouse at the
end of a drag&drop operation, the
OnDragDrop event is triggered. This event has
almost the same signature as the DragOver
event handler: it doesn't have the Accept
parameter. For the left listbox, this means the
eventhandler can be coded as follows:

OnStartDrag

This event is called whenever a drag-&-drop


operation is started. This will change the cursor
to a drag&drop cursor and initiates the other
drag&drop events.
OnDragOver

This event called when something is dragged


over the control. It can be used to indicate
whether the dragged item can actually be
dropped on this control.
OnDragDrop

procedure TMainForm.LBLeftDragDrop(
Sender, Source: TObject; X, Y: Integer);

This event is called when something is dropped


Var LBFrom,LBTO : TListBox;
on the control.
DragCursor

begin
LBFrom:=(Source as TListBox);
LBTo:=(Sender as TListBox);
DragKind
This can be used to decide whether dragging the If (LBTo=LBFrom) then
MoveItemsToIndex(LBTo,LBTo.GetIndexAtXY(X,Y))
mouse starts a drag&drop operation or a
else

Cursor to display during the drag&drop


operation.

docking operation.

MoveItemsToListBox(LBTo,LBFrom,LBTo.GetIndexAtXY(X,Y));

Typical use for these events is to implement a


end;
drag&drop operation between 2 lists (be it a
listview, listbox or tree), or within a single list, to
The MoveItemsToIndex and
reorder the items in a list. This will be
MoveItemsToListbox handle the
demonstrated with a small application using
reordering of the items and copying of items,
two listboxes. Moving the items between the
respectively. The X and Y parameters are used
listboxes can be done using buttons, but also
to determine at what position the items should
with drag and drop. The items can also be rebe inserted. That is all there is to it. The
ordered in a listbox, again using drag-and-drop.
Lazarus application in action can be seen in
The demo application has two listboxes (called
figure 2 page 14.
LBLeft and LBRight). Both listboxes must
have their DragMode property set to
dmAutomatic. To make it more interesting,
they have their MultiSelect set to True.
For this simple example, the OnStartDrag
event will not be used. But the DragOver
event will be used. This event has the
following parameters:
Sender

Is the control that triggered the event


(LBLeft in this case).
Source

This is normally the control that initiated


the Drag&Drop operation (but it can be
manipulated).
X,Y

The coordinates of the mouse relative to the


control.
Accept

A boolean parameter that must be set by the


routine to indicate whether a drop on this
control is allowed.
Knowing this, the OnDragOver event of the
LBLeft listbox can be codes as follows to
accept drops from itself, or from the right
combobox:
procedure TMainForm.LBLeftDragOver(Sender,
Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept:=(Source=LBLeft) or (Source=LBRight);
end;

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

Figure 2 : Drag and drop in action

5 MORE ADVANCED DRAG AND DROP


As shown, drag and drop can be implemented
rather easily for simple cases: the source and
target control are on the same form, there are
only 2 controls, so checking is easy. But when
multiple forms are in play, or there are many
controls, some of them created dynamically,
then the implementation becomes more difficult.

11

STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 4/5
How can the Memo, Listview or ListBox
Drag&Drop operations are handled internally
controls on the secondary forms communicate
in the LCL and VCL using a TDragObject
class. The LCL and VCL differ somewhat in the
to the main form what items are dragged by the
descendent objects that they make available,
user ?
but other than that the mechanisms are
For this, a descendent of TDragObject is
identical.
created which can contain the items that will be
The VCL and LCL allow the programmer to
dragged. Since all controls show lists of strings,
create a custom instance of TDragObject
this object will have a property called Items of
when the drag operation is started: the
type TStrings:
OnStartDrag event handler can be used for
// For Delphi, the parent class is TDragControlObject
this. This instance is then used as the Source
TStringsDragObject = Class(TDragObjectEx)
parameter of the OnDragOver and
private
OnDragDrop events, instead of the control
FItems: Tstrings; // to keep the items in.
that started the drag operation.
procedure SetItems(const AValue: Tstrings);
Public

By creating a descendent of the TDragObject Constructor Create(AControl : TControl); override;


class, it is possible to pass any desired
Destructor Destroy; override;
information to the event handlers used in the
Property Items : TStrings Read FItems Write SetItems;
Drag&Drop operation.
end;
To demonstrate this, we will extend the listbox
example: First of all we'll make it an application
with multiple forms:
A form with a listbox (TListBoxForm).
A form with a memo (TMemoForm).
A form with a listview (TListViewForm)
A main form with a listbox, and 3 buttons to
create the above secondary forms, as often as
the user clicks on the button.

NOTE that the base object for Delphi is named

differently than in Lazarus


TDragControlObject instead of
TDragControlEx.
The constructor with the TControl typed
parameter is introduced in different classes.
Other than that, the code is identical.
The methods of this class are self-explanatory,
they just do some memory management.
procedure TStringsDragObject.SetItems(const AValue: Tstrings);

Each of the forms, when created, first


sets the caption of the form to some
begin
unique text so the window can be
if FItems=AValue then exit;
identified by the user. Then it
FItems.Assign(AValue);
populates the control it has, with
end;
some items. NOTE that these secondary
forms all contain controls that somehow can
constructor TStringsDragObject.Create(AControl : TControl);
begin
represent a list of strings, which the
inherited Create(AControl);
user can select. From each of these
FItems:=TStringList.Create;
secondary forms, the user will be
end
;
able to drag items from the list to
the listbox on the main form.
destructor TStringsDragObject.Destroy;
In the main form, the procedures
begin
to create a secondary form are
FreeAndNil(FItems);
quite simple, and look like this:
inherited Destroy;
end;

procedure
TMainForm.BListBoxWindowClick(Sender: TObject);
begin
With TListBoxForm.Create(Self) do
Show;
end;
NOTE that no reference to the created forms is

kept: this means that the main form cannot


directly check where a drag operation was
initiated, and therefor cannot decide whether
a drop on the listbox is allowed or not.
12

This object is implemented in a separate unit:


dragdroplist, which is used in all forms of the
project.
An instance of this object can be created in the
OnStartDrag event handlers of the listview,
listbox and memo controls of the secondary
forms. When the object is created, it is filled with
the currently selected items in the control.
For the ListBoxForm, the OnStartDrag event
handler that creates an instance of this class
looks as follows:

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 5/5
procedure TListBoxForm.LBItemsStartDrag(Sender: TObject;
The biggest part of this routine has in fact
var DragObject: TDragObject);
Var SDO : TStringsDragObject; I : Integer;
begin
SDO:=TStringsDragObject.Create(LBItems);
DragObject:=SDO;
For I:=0 to LBItems.Count-1 do
If LBItems.Selected[i] then
SDO.Items.Add(LBItems.Items[i]);
end;

After creating an instance of


the TStringDragObject
class, its Items property is
filled with the selected items
from the listbox. Similar
code can be created for the
listview and memo forms.
The start of the drag
operation is herewith
modified, and now the drop
end of the operation must
still be handled.
For this, the OnDragOver
event of the main listbox
must be modified, so it
checks that the Source
parameter is a
TStringDragObject,
in which case it knows it can
accept the items, and
therefore a drop is allowed
procedure TMainForm.LBMainDragOver(Sender,
Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept:=Source is TStringsDragObject;
end;

All that remains to be done, is implementing


the actual drop. Here again, the Source
parameter will be the TStringDragObject,
and this can be used to determine the items that
must be added to the listbox:
procedure TMainForm.LBMainDragDrop (Sender,
Source: TObject; X, Y: Integer);
Var I,L : Integer; SDO : TStringsDragObject;
begin
L:=LBMain.GetIndexAtY(Y);
If L=-1 then
begin
L:=LBMain.Count-1;
If L=-1 then
L:=0;
end;
SDO:=Source as TStringsDragObject;
For I:=SDO.Items.Count-1 downto 0 do
LBMain.Items.Insert(L,SDO.Items[i]);
end;

little to do with Drag & Drop: The position


in the list of the drop is calculated (with
some safety checks): that is where the items
will be added. Note that for Delphi, the first
line must be changed to

L:=LBMain.ItemAtPos(TPOint.Create(X,Y),true);

Once the position is known, all items from


the TStringDragObject instance are
copied over to the listbox. The final
application (in Lazarus) can be seen in
figure 3.

Figure 3 : Extended drag and drop in action

Conclusion
This article has shown that Drag&Drop is
really easy to implement be it from a file
manager to a program or inside a program:
It makes the operation of the program more
intuitive for the user, so adding Drag&Drop
should be considered by any Delphi or
Lazarus programmer, when it is appropriate
for the functioning of the program. One form
of drag&drop has not yet been discussed, and
that is dragging from one program to for
example the file manager. Exploring this is
left for a future contribution.

13

WE CONGRATULATE FASTREPORT WITH THE WINNING OF THE


BLAISE PASCAL MAGAZINE1ST PRIZE AWARD 2015

I
LA S

E
B

IT ALL STARTED WITH AN IDEA.


Fast Reports started their way creating
reporting tools in 1998. Back then
Michael (CEO) and Alexander (CTO)
once had to create components to
integrate for themselves, while
working together for a different
company. As it turned out - it was a
solution to may people's problem.
Some time later FastReport became
developers' lifesaver. That was the
year FastReport VCL was born.

FOR

The company started growing:


from a tiny office in the basement to wide
recognition, certain number of employees,
awards, such as Delphi Product of the Year and
new products (data analysis tool FastCube was
released in 2007).
Nowadays Fast Reports is an international
company known for its state-of-art reporting
software applications, libraries and add-ons that
guarantee fast reporting for developers of the
business software.
Fast Reports has a strong team of almost 30
employees all over the world. Having a group of
likeminded people helps to excel on every level,
whether it's working, creating or traveling.
Here are the solutions that Fast Reports is happy
to offer to its customers:

A G A Z I NE
CA L M
S
A
EDITORS CHOICE
1st PRIZE
AWARD WINNER

2015

Fast Reports
Reporting must be Fast!
FASTREPORT VCL:
FastReport VCL is an add-on component that
allows your application to generate reports
quickly and efficiently. FastReport provides all
the tools necessary for developing reports,
including a visual report designer, a reporting
core, and a preview window. Also available
Lazarus edition.
FASTREPORT FMX 2:
FastReport FMX 2 is a Multi-platform report
generator for Apple Mac OS X and Microsoft
Windows, compatible with Embarcadero RAD
Studio XE (FMX library), FireMonkey FM3.
FASTCUBE FMX, FASTCUBE VCL 2:
FastCube enables you to analyze data and to
build summary tables (data slices) as well as
create a variety of reports and graphs both
easily and instantly. It's a handy tool for the
efficient analysis of data arrays.

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 1/15


MEET THE ESP8266. BY BOIAN MITOV
Last year I introduced you to visual development for
Arduino with Visuino, in a series of 4 articles ending
with an article on Ethernet socket communication
between Arduino and Delphi application.
I also promised to continue with more articles on
Internet Of Things, and Arduino to Arduino
communication.
Since that last article, a lot has happened.
The Raspberry Pi Zero made a splash as a $5
microcomputer, and for a good reason.
However, while the Raspberry Pi Zero was sealing
the spotlight, and the Arduino was dominating the
micro controllers, there was something else lurking
bellow the surface, and rapidly gaining momentum.
Something even bigger, or as it turns out, actually
smaller.
Meet the ESP8266.

Yes, you heard it right. Not a catchy name, and


yet this is probably the biggest thing to happen
in the IoT world yet, and it already has made a
huge impact.
Much like the Japanese companies in the old
days, the Chinese companies nowadays tend to
have the bad rap of cheap knockoffs. I am not
sure what exactly was the day, or the product
that changed the perception of Japanese
companies from cheap copycats, into superior
engineering designers, but as far as I am
concerned the ESP8266 appears to be exactly
such product for the Chinese industry.
This is a genuine chip developed by the Chinese
company Espressif, and, as far as I know, it is
superior to anything else available.
When it was originally introduced in 2014, it
came with 80 MHz, 32 bit RISK CPU, 64KiB
Instruction RAM, 96KiB Data RAM, option for
external flash up to 10MiB, 16 GPIO pins, 1 10-bit
ADC, SPI, I2C, I2S, 3 Serial Ports, and most
importantly on the chip WiFi, and all this on a
single roughly 5x5 mm chip, powered by 3.3V.
In essence this was a powerful, single chip,
ready to use WiFi enabled, IoT device.
Oddly enough the chip was initially marketed in
the form of low cost WiFi ESP-01 communication
module for Raspberry Pi, and Arduino boards.
When I wrote the Ethernet article, I mentioned
the ESP8266 module, as one of the ways
supported in Visuino, to connect Arduino
boards over WiFi. The ESP-01 module is a small
board 14.3x24.8 mm with the ESP8266 chip,
some flash, and on-board WiFi antenna.

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

The module was designed to be controlled over


serial communication by another board, and to
handle all WiFi tasks internally.
Being available for less than $2 it rapidly
became the WiFi solution of choice for many
Arduino and Raspberry Pi users.
What was hidden in the module was that it also
was fully programmable, and even had 2 GPIO
pins available for general purpose tasks on the
board.
The ESPRESSIF company also offered an SDK
for programming the module.
It did not take long before some people noticed,
and started programming the module as a
cheap WiFi enabled stand alone controller,
capable of being powered by a small 3.3V LiIon battery.
While this was happening ESPRESSIF released
a number of other versions of modules with the
ESP8266 chip ESP-02, 03, 04, 05, 06, 07, 08, 09,
10, 11, 12, 12E, 12F, and 13 .
From those probably the most interesting and
popular is the ESP-12. The module is similar
size to the venerable 01, at 16x24 mm, but packs
up to 11 GPIO pins in its E version, 3 serial
ports, one ADC, end exposes the SPI and I2C
pins, all this again for a price of around $2. This
is a very capable stand alone controller with
built in WiFi capability.
The story does not end here.
As I am writing this article, the ESPRESSIF has
started shipping beta versions of their new
ESP32 chip.
The details are still sketchy, but from what is
known, it features Dual core 160 MHz
processor, ~400KiB RAM, faster WiFi up to
144.4 Mbps, more ADC inputs, over 30 GPIO
pins, touch enabled pins, and Bluetooth Low
Energy and Classic.
The ESP8266 modules were here, and there was
SDK for them. The problem was that few
people were familiar with the SDK, and it was
designed for the more experienced developers.
The rest of the community took notice however
and jumped to action. One of the ESP8266
projects was a Lua programing for ESP8266
modules. The Lua project also needed an easy
way to program the modules, and created a
host board with USB connector on it as well as
power adapter for 3.3V and all the necessary
parts for easy programming the ESP controller.

15

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 2/15


These hosting boards were called NodeMCU,
and although a bit more expensive in the $5-$8
range depending on the version, they are
currently the easiest way to start with the
ESP8266 development.
While the Lua group was busy with their
development, another group focused on making
Arduino library interface for the ESP8266
module, thus in the second part of last year, it
became possible to program ESP8266
modules with the Arduino IDE using the same
API.
It did not take long for me to notice, and to
start working on Visuino support for the
ESP8266.
At present the Visuino has full support for the
Digital, Analog pins, of the ESP, the I2C, SPI,
Serial, and the WiFi networking.
Since I already promissed to write an article on
IoT with Visuino, and the ESP Modules are
probably the best option for IoT, I decided to
make this article using ESP8266 modules.
Most of it can be used with other Arduino
compatible boards, but they will require
additional hardware for the networking.
A simple IoT project is a remote thermostat.
We will use 2 NodeMCU modules. We will
attach Thermometer to one of the modules,
and Relay to the other.
The first module will read the temperature and
send it over WiFi to the second one, and the
second one will control the relay based on
temperature.
There are many ways we can setup the 2
modules to talk to each other.
First we need to decide how they will be
connected to the same subnet. They can both
connect to existing Hotspot, or one of them can
be a hotspot for the other. In this case I will use
the second approach, one of them will be a
hotspot with SSID Thermometer, and the
other will connect to it. They also can use many
ways to communicate. UDP, TCP/IP Client and
Server sockets are all possible options. In this
case we will use UDP sockets, but if you prefer,
you can modify the project to use TCP/IP.:
First we need to prepare the hardware.
1. We will need 2 ESP8266 modules.
I used NodeMCU version 0.9.
2. One Maxim DS18B20 Thermometer module.
I got my one for about $1 on eBay. You can
use other Thermometer types, but you will
need to change a bit the Visuino project with
a different thermometer component.

16

3.
4.

One Relay module. I got my one also for


about $1 on eBay.
6 Female-Female jumper wires

Next we need to connect the thermometer to


one of the ESP8266 modules: Connect 3 jumper
wires to the 3 pins of the Thermometer module
for the Ground (-)(Black wire), Power (+)(Red
wire), and Signal (Yellow wire)

Connect the other end of the Signal wire


(The yellow wire on the picture) to the D2 pin
of the NodeMCU ESP8266 module:

Connect the other end of the Ground wire


(Black wire) to the Ground pin of the
NodeMCU ESP8266 module. Connect the other
end of the Power(+) wire(Red wire) to the 3.3V
pin of the NodeMCU ESP8266 module:

The Thermometer module is ready. Now we


need to prepare the Relay module:
Connect 3 jumper wires to the 3 pins of the
Relay module for the Ground(-)(Black wire),
Power(+)(Red wire), and Signal(Yellow wire):

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 3/15

Connect the other end of the Signal wire


(The yellow wire on the picture) to the D2 pin
of the second NodeMCU ESP8266 module
as we did with the Thermometer module.
Connect the other end of the Ground wire
(Black wire) to the Ground pin of the second
NodeMCU ESP8266 module.
Connect the other end of the Power (+) wire
(Red wire) to the 5V pin of the second
NodeMCU ESP8266 module:
For the Additional Boards Manager URLs, in
the Preferences dialog set one of the following:
If you want to use the stable release of the
ESP8266 libraries:
http://arduino.esp8266.com/stable/
package_esp8266com_index.json
If you want to use the latest staging version of
the ESP8266 libraries:
http://arduino.esp8266.com/staging/
package_esp8266com_index.json

Before we can program the ESP8266 modules,


we need to add the ESP8266 boards support in
the Arduino IDE. The latest versions of the IDE
comes with boards manager that makes it very
easy to install support for new boards and their
tool chains.
Start the Arduino IDE. I recommend you to use
version 1.6.7 at present. Avoid version 1.6.6 as
there are a lot of critical bugs in it.
From the Menu select |File|Preferences|:

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

17

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 4/15

Click OK.
The ESP8266 project is
available on github here:
https://github.com/
esp8266/Arduino
I used the Staging
version, however, I had
some issues with it, and
had to manually get the
latest changes with GIT.
From the Menu select
|Tools|Board:......|Boards
Manager...|:

In the text box of the


Boards Manager type
ESP, then select the
esp8266 by ESP8266
Community and click
on the Install button:

18

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 5/15

The installation will take some time to download


and install all the ESP8266 tools and libraries:

When the installation finishes, clock on the Close button:

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

19

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 6/15

After the installation, you may decide to get the


latest files from GIT as I did.
If you need to do this, the Arduino by default
installs the ESP8266 support in this directory:
C:\Users\{USER_NAME}\AppData\Local\
Arduino15\packages\esp8266
You can check out the latest files from github
with GIT and then you can use BeyondCompare
or other tool to merge the files into
C:\Users\{USER_NAME}\AppData\Local
\Arduino15\packages\esp8266
directory.
Now that the Arduino IDE is ready to program
ESP8266 modules, we can start with our project.

From the list select the ESP8266 board that you


will use. I have ModeMCU ESP-12, so I selected it:

First we will program the Thermometer module.


Start Visuino. To select the type of the ESP8266
board that you will use, click on the
button
of the Arduino component:

Next we need to set the board as WiFi Hotspot


with SSID Thermometer.
In the Object Inspector, expand the Modules
property, then the WiFi sub property, then the
AccessPoint sub property.
Set the value of the SSID sub property of the
AccessPoint, to Thermometer:

20

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 7/15

To make sure the Access Point will be on the 200.200.200.X subnet, we need to assign a fixed address.
Expand the Config sub property of the AccessPoint property. Set the value of the Enabled sub
property of the Config to True. Set the value of the IP sub property to 200.200.200.100:

Next we need to add a UDP socket for the communication. In the Object Inspector, click
on the
button next to the value of the Sockets sub property of the WiFi:

In the Sockets editor select UDP Socket, and


then click on the
button
In the Object Inspector set the value of the
RemotePort to 8888:

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

21

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 8/15


In the Object Inspector, set the value of the
RemoteIPAddress property to
200.200.200.200 this is the fixed IP address
that we will assign to the other module later on:

The connection is ready. Next we need to add a


Thermometer component.
In the filter box of the Component Toolbar,
type ther, then select the Maxim 1-Wire
Thermometer component:

and drop it in the design area in the


center.
Connect the OneWire output pin of
the Thermometer1 component to the
Digital input pin of the Digital[ 2 ]
channel of the NodeMCU ESP-12
component:

The easiest way to send the data is in binary


floating point format. For this we will use a
structure component with a single floating point
binary element to make the UDP packet.
In the filter box of the Component Toolbar, type
make, then select the Make Structure
component:

And drop it in the design area


in the center.
Click on the
button of the MakeStructure1
component:

In the Elements editor select


the Analog element, and then
click on the
button:

22

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 9/15

to add Analog element:

The project can be used as it is, but if you


run it it will overwhelm the network with
UDP packets, as it will keep sending
thermometer readings very fast one after
another. It is better to read the
thermometer only once a second. The
Thermometer component has a Clock
pin, that can be used to control when the
thermometer will perform a reading and
send the value to the socket. We will use a
Clock Generator component to control the
Thermometer.
In the filter box of the Component
Toolbar, type clock, then select the
Clock Generator component:

Then close the dialog.


Connect the Out pin of the Thermometer1
component to the In pin of the
Elements.Analog1 element of the
MakeStructure1 component:

And drop it in the design area in


the center.
Connect the Out pin of the
ClockGenerator1 component to the
Clock pin of the Thermometer1
component:

Connect the Out pin of the MakeStructure1


component to the In pin of the
Modules.WiFi.Sockets.UDPSocket1 of the
NodeMCU ESP-12 component:

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

23

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 10/15


The Thermometer project is ready. Now you can click on the
ESP8266 code, and open the Arduino IDE:

button, or press F9 to generate the

Connect with USB cable the first NodeMCU module (the one with the Thermometer connected to it)
to the computer. In the Arduino IDE from the menu select the type of the board that you have.
In my case this is NodeMCU 0.9 (ESP-12 Module):

24

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 11/15


Also from the Arduino IDE menu, select the
Serial Port to which the module is connected:

Click on the
upload the

button to compile and


code to your module:

The Thermometer module is ready.


Now we will program the Relay module.
Start a new Visuino project, and select the
module as we did in the previous project.
Next we need to add a remote access point to
which the module will connect.
In the Object Inspector, expand the Modules
property, then the WiFi sub property, then
the AccessPoints sub property, and click on
the
button next to its value:

In the AccessPoins editor, select


WiFi Access Point, and then click on the
button to add the access point

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

25

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 12/15


In the Object Inspector, set the value of the SSID property to Thermometer:

In the Object Inspector, expand the Config property, and set the value of the Enabled
sub property to True:

In the Object Inspector, set the value of the IP sub property to 200.200.200.200:

This will assign a fixed IP address of 200.200.200.200 for the module.


Close the AccessPoints editor.
Next we need to add UDP socket for the communication. In the Object Inspector, click
on the
button next to the value of the Sockets sub property of the WiFi
property

In the Sockets editor add an


UDP Socket as you did in
the previous project.
In the Object Inspector set the
value of the Port property
to 8888:

26

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 13/15

Then close the Sockets editor.


The Thermometer module sends the temperature in binary floating point form as a packet. We need
to decode it properly. For this we need a Split Structure component with Analog element in it.
In the filter box of the Component Toolbar, type split, then select the Split Structure component:
And drop it in the design area in the center.
Click on the
button of the SplitStructure1 component:

In the Elements editor select the Analog element, and then click on the
to add Analog element:

button:

Then close the Elements editor.


We need to turn on the relay when the temperature reaches above some temperature. For this we
can use Compare Analog Value component.
In the filter box of the Component Toolbar, type compar, then select the Compare Analog
Value component:
And drop it in the design area in the center.
In the Object Inspector set the value of the CompareType property to ctBigger:

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

27

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 14/15


In the Object Inspector set the value of the Value property to the temperature in Celsius above which
we want to turn the Relay on, as example 20:

Connect the Out pin of the Modules.WiFi.Sockets.UDPSocket1 of the NodeMCU ESP-12


component, to the In pin of the SplitStructure1 component.

Connect the Out pin of the Elements.Analog1 element of the SplitStructure1


component to the In pin of the CompareAnalogValue1 component:

Connect the Out pin of the CompareAnalogValue1 component to


the Digital input pin of the Digital[ 2 ] channel of the NodeMCU ESP-12 component:

The Relay project is ready. Now you can click on the


button, or press F9 to generate the ESP8266 code, and open the Arduino IDE:

28

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 15/15

Connect with USB cable the second NodeMCU module(the one with the Relay connected to it) to the
computer. If necessary in the Arduino IDE, select the module board type, and serial port, as you did for
the previous project.
Click on the

button to compile and upload the code to your module:


You are done. If you power the two
modules, they will automatically connect
to each other and if the temperature
measured by the module with the
thermometer goes above 20 degrees, the
second module will turn the relay on. If
the temperature drops bellow 20 degrees,
the relay module will turn the relay off.
CONCLUSION
So far in 5 articles you have learned
how to create simple Arduino
projects with Visuino, how to
communicate between Arduino and
Delphi, over Serial Port, and
Ethernet, how to create your own
Visuino components, and finally how
to program ESP8266 modules to
communicate with each other as part
of Internet Of Things solution.
In the following issues I will continue
with even more interesting projects,
connecting different type of modules
together, as well as integrating them
with web servers into the even more
exciting world of the Internet Of
Everything.

Issue Nr 10 2015 BLAISE PASCAL MAGAZINE

29

BELGIUM
Practicum: Delphi 10 Seattle with VCL and Mobile Development
1-Day Practicum
March 3, 2016 - Hotel Ter Elst Edegem (BE)
During this session you will start using Delphi 10 Seattle together with presentors Pawel
Glowacki and Danny Wind. Six differtent topics are covered this day.
Every topic will take about one hour. Pawel or Danny will explain more about the specific
topic and show you some code. After this you will get some time for practices using the
training materials written by Pawel and Danny.
Topics this day are:
how to build VCL Windows 10 applications
integrate with the new Windows 10 API
the use of the Parallel Programming Library for responsive applications
access to databases using FireDAC
create scalable and multitier solutions with DataSnap and REST
build and publish apps for the Google Play and iOS AppStore
During this Practicum you can bring your own laptop with Delphi 10 Seattle Enterprise
installed.The special price of this Practicum is 99,-- excl. VAT when you have bought or
will buy the 10 Seattle version via Barnsten. Also customers with an active Update
Subscription can join this practicum for 99,00 excl. VAT.
Otherwise the price is 295,00 excl. VAT.

or call: +31 (0)235422227


http://www.barnsten.com/default/development-tools/training/
practicum-delphi-10-seattle-met-vcl-en-mobile-ontwikkeling

NEDERLAND
TRAININGEN
Barnsten organiseert in samenwerking met Danny Wind van de Delphi Company diverse
Delphi en FireMonkey trainingen. Het doel van de trainingen is u, als Delphi ontwikkelaar,
snel productief te laten werken. Er zijn zowel Essentials als Advanced trainingen en
daarmee aanbod voor zowel de beginnende als de ervaren Delphi ontwikkelaar. Tijdens de
trainingen maakt u gebruik van uw eigen laptop met daarop Delphi 10 Seattle inclusief
InterBase XE7 genstalleerd (eventueel trial versie).
Datum

Training Locatie Prijs

27-29 januari
17-18 februari
3 maart
11 maart

Delphi Essentials VCL Training = VOLGEBOEKT


Delphi Update FireMonkey & Android
Practicum: Delphi met VCL en Mobile Ontwikkeling
Migratietraining BDE en Unicode (halve dag)

Capelle a/d IJssel


Amersfoort
Edegem (BE)
Amersfoort

1.350,00
895,00

99,00
295,00

or call: +31 (0)235422227


http://www.barnsten.com/nl/development-tools/training

THE TMS LCL HW PACK FOR RASPBERRY PI


OPEN-SOURCE PACKAGE
starter

PAGE 1/5

The protocol is described here:


https://en.wikipedia.org/wiki
/I%C2%B2C. In a nutshell, data is digitally
serialized and sent on a bus. By means of an
address + read/write instruction, data can be
read or written from a master who drives the
clock. In this case, the master is the Raspberry Pi.

expert

INTRODUCTION
At TMS software, we have recently published a first
version of the free and open-source TMS LCL HW
Pack for Raspberry Pi that you can download from:
http://www.tmssoftware.com/site/tmslclhwpack.as
p. The goal of the TMS LCL HW Pack for Raspberry
Pi is to make it very simple to do IO from Pascal
SDA
applications. One of the things that makes the
SCL
Raspberry Pi so versatile is its IO capabilities,
B1
B2
S
especially the Raspberry Pi 2 with a 40 pins header
that exposes generic GPIO pins, I2C, UART and SPI
Serialized data on the i2c 2-wire bus.
pins.

BN

tmssoftware.com
productivity software buiding blocks

Raspberry Pi 2 40 pin header

The generic GPIO pins are pins that can be


programmatically configured as digital inputs
and outputs. There are 6 such generic GPIO pins
for a Raspberry Pi 2.Under programmatic control,
you can set a logic 1 or 0 for these pins that
translates into a VCC or GND signal on the pin or
you can read the voltage VCC or GND on the pin
as either 1 or 0. This is useful for digital signals
but sadly the Raspberry Pi doesn't offer built-in
analog programmable pins like the Arduino does.
Next is the i2c bus, which is a two-wire protocol to
read & write data on a bus of i2c devices.

Typical connection between i2c master and slaves

The next option is the SPI bus


(https://en.wikipedia.org/wiki/
Serial_Peripheral_Interface_Bus)
which is a 4 wire bus protocol also based on
master/slave principle where the Raspberry Pi is
the master. Along with a device select signal and
serial clock, there are two data wires, one for
input and one for output.

Typical connection of
an SPI master to
SPI slaves

31

THE TMS LCL HW PACK FOR RASPBERRY PI PAGE 2/5


THE TOWERS OF
HANOI PAGE 2/4
OPEN-SOURCE
PACKAGE
Finally, the last option on the 40 pin connector is
a classic UART or serial port with TX, RX pins to
do classic serial port communication. In this
article, we'll focus on the i2c and SPI ports.
GETTING DEVICES TO EXTEND YOUR
RASPBERRY PI

Lots of devices exist that can extend your


Raspberry Pi. From off the shelve ICs with i2c or
SPI interfaces that you use together with some
control circuitry and connect to the Raspberry Pi
header to ready-made little boards or extenders
from well-known companies such as Adafruit
(www.adafruit.com) or Sparkfun
(www.sparkfun.com)
USING I2C

Each i2c device on the i2c bus has a 7bit address


meaning that theoretically 128 devices can be
connected. Data is serially transmitted and the
clock rate can be selected. 400kbs is a realistic
speed that can be used also with devices
connected to the Raspberry Pi via a breadboard.
Typically, along with the address, data is written
or read in blocks of 8 bit. In order to make
accessing i2c devices easily accessible from
Pascal applications, we have created a base class:
TTMSLCLRaspiI2C. This class has property
I2CAddress to set the address of the i2c device
you want to access and I2CPort to select what
I2C port of the Raspberry Pi to use. To make a
connection to an i2c device, call the function
TTMSLCLRaspiI2C.Open: boolean. To close the
connection again, there is the
TTMSLCLRaspiI2C.Close function and with
TTMSLCLRaspiI2C.Connected: boolean, you
can check at all times the connection state. When
there is a connection, you can write one byte of
data to the device with
TTMSLCLRaspiI2C.SetByteRegister and read
with TTMSLCLRaspiI2C.GetByteRegister.

ENCAPSULATING I2C DEVICE


FUNCTIONALITY

Typically, a useful communication with an i2c


device comes down to read & write bytes in
the proper and desired sequence to get the
device to do something useful. We have
therefore created a number of classes that
descend from TTMSLCLRaspiI2C and that
encapsulate typical setup & communication
with commonly used i2c devices:
- TTMSLCLAdaQuad7SegLed:

component to control a quad 7 segment LED


- TTMSLCLAdaADC12B:

component to read data from a


quad analog digital convertor
- TTMSLCLADADAC12B:

component to write data to a


digital analog convertor
- TTMSLCLADADISPL128X32:

component to drive a 128x32 OLED display


- TTMSLCLAdaDispl16x2:

component to drive a 16x2 LCD display and


read its 5 key inputs
- TTMSLCLAdaBarTemp:

component to retrieve temperature & barometric


data from a sensor
- TTMSLCLAdaI2CIOExpander:

component to control 16 i2c addressed


extra GPIO pins
- TTMSLCLAda8x8MatrixLed:

component to drive a 8x8 LED matrix

Interface of the base i2c class:


TTMSLCLRaspiI2C = class(TComponent)
public
constructor Create(AOwner: TComponent); override;
function Open: boolean; virtual;
function Close: boolean; virtual;
function Connected: boolean;
function SetByteRegister(RegNo: Integer; Val: Byte): Integer;
function GetByteRegister(RegNo: Integer): byte;
published
property I2CAddress: integer read FI2CAddress write FI2CAddress;
property I2CPort: CInt read FI2CPort write FI2CPort;
end;

i2c quad 7 segment LED

i2c 128x32 OLED display

32

tmssoftware.com
productivity software buiding blocks

Issue Nr 1
102016
2015
BLAISE
BLAISE
PASCAL
PASCAL
MAGAZINE
MAGAZINE

THE TMS LCL HW PACK FOR RASPBERRY PI PAGE 3/5


OPEN-SOURCE PACKAGE
At this time, there is one component
descending from TTMSLCLRaspiSPI that
controls the TTMSLCLAdaFram8KSPI device,
an 8K FRAM device.

i2c digital analog convertor

i2c 4 channel analog digital convertor


SPI 8k FRAM

Reading and writing in the FRAM (ferroelectric memory that can keep its memory
also when not powered) is simple with read &
write commands per byte:
function WriteByte(Adr: word; val: byte): boolean;
function ReadByte(Adr: word; var val: byte): boolean;
i2c 16x2 LCD display
+ 5 key keypad

i2c 8x8 LED array

i2c temperature
& barometric sensor

i2c 16 channel GPIO extender

USING SPI
The SPI protocol is similar to i2c and is
encapsulated in the class TTMSLCLRaspiSPI. It
has a PortNum property to select the Raspberry Pi
which one of the two SPI ports to use. There is no
device address involved with SPI as a device on
SPI is accessed by driving the device selector pin
low for the device. This limits the number of
devices that can be directly connected to the
Raspberry Pi. The Raspberry Pi SPI clock speed is
configurable and maximum speed is 125MHz. The
TTMSLCLRaspiSPI class also has Open & Close
functions and a Connected property to read the
state. To transfer data via SPI to a device, there are
also the functions SetByteRegister and
GetByteRegister. In addition, there are functions:
ReadTransfer and WriteTransfer.

PUTTING IT TOGETHER IN A FUN


PROJECT

To put the pieces together, we create a small


project. We'll use the TTMSLCLAdaBarTemp
component to read out temperature and air
pressure from this BMP180 sensor. The values
read will be displayed alternatingly on a
128x32 pixel OLED screen connected to the
Raspberry Pi. While both devices are i2C
devices, there is one thing particular about
the 128x32 OLED screen and that is that it
needs to get a reset pulse to get initialized. So,
the TTMSLCLAdaDispl128x32 assumes the
Raspberry Pi GPIO pin 17 is connected to the
RST pin of the 128x32 OLED screen as its
method TTMSLCLAdaDispl128x32.InitGPIO
will configure and pull this RST pin low to
reset the device.
ASSEMBLING THE HARDWARE

To quickly put the hardware together, you


can use a breadboard and a 40 pin flatcable
with breadboard connector. Wire up the
Raspberry Pi connector signals GPIO 2 (SDA)
to the SDA pin on both the Adafruit BMP180
(https://www.adafruit.com/
products/1603) and 128x32 OLED (See:
https://www.adafruit.com/
products/931). Do the same for GPIO 3
(SCL) to the SCL pin.
function ReadTransfer(buf: pointer; wsize, rsize: integer): boolean;
function WriteTransfer(buf: pointer; wsize: integer): boolean;
Connect a connector GND
and VCC pin also the BMP180
and 128x32 respective GND and VCC pins.
Read transfer will send wsize number of bytes
Finally, the temperature and barometric
from the buffer pointed to by buf and read back
sensor requires a 3V3 pin, so connect this to a
in the buffer rsize number of bytes.
Raspberry Pi header 3.3V pin and for the reset
The WriteTransfer function will write wsize
pulse of the OLED display, connect GPIO 17
bytes from the buffer pointed to by buf.
to the OLED128x32 pin RST.

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

tmssoftware.com
productivity software buiding blocks

33

THE TMS LCL HW PACK FOR RASPBERRY PI PAGE 4/5


OPEN-SOURCE PACKAGE

Schema:

procedure TForm1.FormShow(Sender: TObject);


begin
// this initializes GPIO 17 and pulse
// the reset pin on the display low to initialize
displ.InitGPIO;
// open the display and show a startup text
if displ.Open then
begin
displ.Clear;
displ.DrawTextLarge(0,4,'Ready....');
displ.Display;
end;
// open the sensor
sensor.Open;
end;

Hardware assembled on a breadboard

Putting the software together


To access the BPM180 sensor, drop the
component TTMSLCLAdaBarTemp on the form
and set its name to 'sensor'. For the OLED
display, drop the TTMSLCLAdaDispl128x32 on
the form and set its name to 'displ'. Drop a
TCheckBox and TTimer on the form and set the
TTimer interval to 2000ms and Enabled to false.

Next, to start displaying the temperature and


air pressure alternatingly, check the checkbox
to start the timer:
procedure TForm1.CheckBox1Change(Sender: TObject);
begin
timer1.Enabled := Checkbox1.Checked;
end;

Then, from the TTimer.OnTimer event,


alternatingly we read the temperature and air
pressure from the sensor and show it on the
display:

In the form's OnShow event, we'll open the


connection the BPM180 and OLED display by
calling the Open method:
34

tmssoftware.com
productivity software buiding blocks

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

THE TMS LCL HW PACK FOR RASPBERRY PI PAGE 5/5


OPEN-SOURCE PACKAGE
procedure TForm1.Timer1Timer(Sender: TObject);
var
f: single;
s: string;
begin
if sensor.Connected then
begin
if ShowTemp then
begin
f := sensor.GetTemperature;
s := 'T:' + Format('%.2f',[f]) + ' C';
end
else
begin
f := sensor.GetPressure;
s := 'P:' + Format('%.0f',[f]) + 'mBar';
end;
displ.Clear;
displ.DrawTextLarge(0,4,s);
displ.Display;
ShowTemp := not ShowTemp;
end;
end;

About the author


Bruno Fierens
Studied civil electronic engineering at university of
Ghent, Belgium (1987-1992) and started a career as
R&D digital hardware engineer. Besides the
fascination for electronics, Bruno Fierens set the first
steps in programming with Turbo Pascal v3.0 and
used all Borland Pascal & Delphi versions since that
time.
In 1996, he founded TMS software for the activity of
application and component development with Delphi.
TMS software became Borland Technology Partner in
1998, developed Delphi Informant award-winning
grid & scheduling components and now has an
international team of software developers working on
a large portfolio of components.
Bruno Fierens is from 2012 Embarcadero MVP and
frequent speaker at Delphi conferences world-wide.
He does and oversees VCL, IntraWeb, .NET and
FireMonkey component development

One important note: configuring the GPIO


pins as input or output on Raspberry Pi
requires admin privileges, so you might want
to make sure the app runs with admin
privileges.

Project in action 1: showing barometric pressure

CONCLUSION
With a few classes that enable you to directly access
hardware extensions for the Raspberry Pi, accessing
this hardware becomes dead-easy and you can fully
focus on being creative hooking up all kinds of
devices to the Raspberry Pi and automating things.
At this time we have classes for 9 hardware
extensions and we're busy developing more for other
extensions. As the TMS LCL HW Pack is an opensource project, we also invite anyone to participate
and share classes that you might have created that
wraps other hardware devices. Yes, it's 2016 and
programming in Pascal has never been more fun!

Project in action 2: showing ambient temperature

tmssoftware.com
productivity software buiding blocks

tmssoftware.com
productivity software buiding blocks

35

36

Issue Nr 1
102016
2015
BLAISE
BLAISE
PASCAL
PASCAL
MAGAZINE
MAGAZINE

THE QUEENS PUZZLE PAGE 1/3 PROGRAMMING DESCRIPTION


starter

expert

BY DAVID DIRKSE
A chessboard has 8 * 8 fields (colums * rows).
The board is painted in paintbox1 on form1. A field
counts 60 * 60 pixels. The queen is a bitmap of 50*50
pixels and is painted by the canvas.draw method.

How many queens are needed minimally to cover all


fields of a chessboard? This Delphi program helps
finding the answer.
Before writing any program the objectives must be
clear. We want to:
1. have the user search for solutions by
adding/removing queens
2. have the program search for solutions
3. interrupt a program search, thus keeping control
4. select the number of queens allowed
USER / PROGRAM MODE
Two SpeedButtons are placed on form1, named
SolveBtn and TryBtn. Their groupIndex is 1, only one
button may be UP the the time.
The buttons share the OnClick event:
procedure TForm1.tryBtnClick(Sender: TObject);
begin
playermode := tryBtn.Down;

type TField = record


Q : byte; // 0: empty 1:queen
lines : byte; //1:-- 2:| 4:/ 8:\
end;
Tpos = record
x,y : byte;
end;
var Qlist : array[1..8] of Tpos; //place of queen on board
Qcount : byte;
board : array[1..8,1..8] of TField;
playermode : boolean = false;

........
end;
Variable playermode is true for allowing the player
to modify the board. If the program searches for a
solution, there are some states:
1. a new search starts
2. a search ends with no solution found
3. a search ends with a solution found
4. a search is temporarily pauzed to keep contact
with the Windows system
Therefore we introduce
type TsearchResult =
(srStart,srSolved,srNoSolution,srTimeout);

.
and the call:
procedure GoSolve(var sr : TsearchResult);
variabele sr defines the start condition and also
reports the exit condition. After a while, the GoSolve
procedure exits with sr=srTimeout just to allow the
processing of messages by the operating system. A
call with sr=srTimeout will resume the search
process. The main tasks during the search is
adding/removing queens to/from a field.
CODING THE BOARD

Tfield.Q = 1 if it holds a queen, else it is 0


Tfield.lines uses bits 0..3 A bit is set if it holds
a line indicating coverage by a queen on another field.
Board[1..8,1..8] is a 2 dimensional array holding all the
fields. Qlist[1..8] is a list of queens by board
position. Qcount is the number of queens on the
board, so the number of valid entries in

Qlist[1..8]
ADD / DELETE QUEENS
To add a queen in field at column i and row j:
procedure addqueen(i,j : byte);
begin
inc(Qcount);
board[i,j].Q := 1;
paintfield(i,j);
fixlines(i,j);
Qlist[Qcount].x := i;
Qlist[Qcount].y := j;
end;

Paintfield(i,j) paints the field, see the source


code for details. Fixlines(i,j) adds horizontal,
vertical and diagonal lines to all fields that are covered
by the new queen. Also for each covered field the
corresponding bit in Tfield.lines is set.
Deleting a queen is very similar, see the source code.
The Fixlines( ) procedure needs some explanation.
FIXLINES(I,J)

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

37

THE QUEENS PUZZLE PAGE 2/3


PROGRAMMING DESCRIPTION

BY DAVID DIRKSE

Say we add a queen at field(3,4)


Then we cover a row from (1,4) . (8,4) and a column
from (3,1) (3,8). The diagonal lines are a problem
and in mind we extend the board left and right.
Now we cover by line / : (-1,8) (6,1) and by line \ :
(0,1) (7,8). These are 8 fields each, but of course we
only paint fields in the range from 1..8.
In general, adding a queen in field (i,j) affects fields:

Qcount holds the number of queens on the


chessboard. Adding a queen increments Qcount
and adds the (i,j) values to Qlist[Qcount].
Deleting a queen decrements Qcount.
All actions (addqueen,deletequeen,next free
field) apply to field[i,j]. Only nextfreefield
modifies i and j , indicating the next free field.

for / starting at (i+j-8 , 1) and next 7 fields diagonally up.


for \ starting at (i-j+1 , 1) and next 7 fields diagonally down.
SOLVING THE PUZZLE
The method used is basically of the type brute force.
This means that simply all possibilities are tried until,
by accident, a solution is found. However, there is a
time saving measure. We do not place a queen on a
covered field which is simply done by avoiding fields
which have .Q > 0 or .lines > 0. Also we must try all
possibilities in a systematical way not to forget
solutions.
Array Qlist[1..8] of Txy holds the (x,y) positions of the
queens and this array is regarded a counter. [1] is the
upper- and [8] is the lower element. A (x,y) field counts
x from 1 ..8 and on overflow y is incremented by 1. So
the first (lowest) count is (1,1) and to upper count is
(8,8). The GoSolve procedure does the work. It is small
but rather tricky and requires concentration to
understand. Below is the flowchart:

At the start, i and j are set to 1,


Qcount = 0. (1,1) is the next free
field and here the first queen is
placed.
The next queens are placed in the next free fields
until the selected queencount is reached.
Next the last queen is deleted at (i,j) and the next
free field after (i,j) is selected.
If no free field is found and the board is empty,
the no-solution exit is taken.
Reloading i,j from Qlist[Qcount] selects the
position of the previous element if a queen was
deleted before which decremented Qcount.

If the maximal number of queens is 4, which are


all placed then number 4 is deleted, but i,j
unchanged. Then a new free field is selected to
place queen number 4. If no free field is found,
then i,j is loaded from queen 3 which is deleted
and a next free field is
searched for.
On the next page is the complete
Gosolve procedure:

38

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

THE QUEENS PUZZLE PAGE 3/3


PROGRAMMING DESCRIPTION

BY DAVID DIRKSE

procedure GoSolve(var sr : TsearchResult);


//try solve puzzle for Qcount number of queens
//maxQueen has been set
var i,j : byte;
fnext : boolean; //solution check flag
timeout : word;
begin
timeout := 0;
case sr of
srStart
: begin
i := 0; j := 0;
end;
srSolved
: begin
i := Qlist[Qcount].x;
j := Qlist[Qcount].y;
end;
srNosolution : exit;
srTimeout : begin
i := saveI;
j := saveJ;
end;
end;
//
repeat
inc(timeout);
if timeout = 100 then
begin
saveI := i;
saveJ := j;
searchresult := srTimeout;
exit;
end;
if (Qcount = MaxQueen) then deleteQueen(i,j);
if nextFreeField(i,j) then begin
fnext := true;
addQueen(i,j);
end
else
begin
fnext := false;
if Qcount > 0 then begin
i := Qlist[Qcount].x;
j := Qlist[Qcount].y;
deleteQueen(i,j);
end
else begin
sr := srNoSolution;
exit;
end;
end; // else
until fnext and checksolution;
sr := srSolved;
end;

A trick is the last line:


until fnext and checksolution ;
In the menu: project/options/compiler, full boolean
evaluation must not be checked.
The expression is false if fnext is false and the
checksolution procedure will not be called.
KEEPING CONTROL
In most cases, the search will terminate after a very
short time. However if it takes longer we want to be
able to terminate the process prematurily. This requires
that Windows is

Issue Nr 1 2016 BLAISE PASCAL MAGAZINE

granted some time to process any pending messages.


The trick here is a timeout variable, called TimeOut. At
the start it is set to zero and it is incremented each time
the repeat loop is executed. If a value of 100 is reached,
the local variables i,j are stored in saveI,saveJ and the
search procedure is exited with the srTimeOut search
result. Upon reentry i,j are reloaded and the search
continues. Let's look who calls the GoSolve procedure:
procedure TForm1.GoBtnClick(Sender: TObject);
begin
if searchbusy then exit;
searchbusy := true;
case searchresult of
srStart : begin
clearPuzzle;
paintBoard;
GoProc;
end;
srNoSolution : msg(11);
srSolved : GoProc;
end;//case
searchbusy := false;
end;
The search result will be stStart after a RESET or after
clearing the board. In the case of a solved puzzle, a new
search is started to find another solution.
WHAT DOES GOPROC
procedure GoProc;
begin
repeat
msg(10);
GoSolve(searchresult);
application.processmessages;
until (searchresult <> srTimeOut)
orresetRequest;
if resetRequest then
begin
ProcReset;
msg(13);
end
else
case searchresult of
srSolved : msg(9);
srNoSolution : msg(12);
end;//case
end;

GoSolve is repeated until there is no timout (so a


yes/no solution).
Also the application.processmessages lets
Windows process pending messages, which
allows the RESET button to be pressed.
Boolean variable resetRequest is set if the RESET
button is pressed while searching is in progress.
For details please refer to the source code listing.

39

Google's Project Loon balloons to cover Sri Lanka with internet access. The Project Loon balloons
are designed to fly through the stratosphere at around 20 km (12.4 mi) above the Earth's surface

Now multimonitor remote desktop V5 (VCL and FMX)


Rad studio and Delphi 10 SEATTLE support
High performance LZ4 and Jpeg compression
Impoved NextGen support including IOS 64 bit
Native high performance 100% developer
defined application server with support for
loadbalancing and failover
Native high performance JSON and XML
(DOM and SAX) for easy integration with
external systems
Native support for RTTI assisted object
marshalling to and from XML/JSON,
now also with new fullfeatured XML schema
(XSD) import
High speed, unified database access
(35+ supported database APIs) with
connection pooling, metadata and
data caching on all tiers
Multi head access to the application server,
via AJAX, native binary, Publish/Subscribe,
SOAP, XML, RTMP from web browsers,
embedded devices, linked application
servers, PCs, mobile devices, Java systems
and many more clients
Full FastCGI hosting support. Host PHP/Ruby
/Perl/Python applications in kbmMW!
AMQP support

Supports Delphi/C++Builder/RAD Studio 2009


to 10 Seattle32 bit (64 bit and OSX where
applicable). kbmMW for Seattle includes full
support for Android and IOS 32/64 (client and
server).!
kbmMemTable is the fastest and most feature rich
in memory table for Embarcadero products.
-

Easily supports large datasets


with millions of records
Easy data streaming support
Optional to use native SQL engine
Supports nested transactions and undo
Native and fast build in M/D,
aggregation /grouping,
range selection features
Advanced indexing features for
extreme performance

Warning!

kbmMemTable and kbmMW


are highly addictive!
Once used, and you are hooked for life!

( Advanced Message Queuing Protocol)


-

Added AMQP 0.91 client side gateway


support and sample.
Fully end 2 end secure brandable Remote
Desktop with near REALTIME HD video,
8 monitor support, texture detection,
compression and clipboard sharing.

COMPONENTS
DEVELOPERS

EESB, 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 WIN32 / 64,
.NET, LINUX, UNIX MAINFRAMES, MINIS, EMBEDDED DEVICES, SMART PHONES AND TABLETS.

You might also like