Delphi Cookbook – 2nd Edition

Delphi Cookbook 2nd Edition

Starting from today my Delphi Cookbook 2nd edition is available to buy. The first edition got a lot of interest and appreciation comments. Delphi Cookbook is a best sellers for PacktPub (my editor) in its category, the editor decided to ask me a 2nd edition. So here it is!

What’s new

The problem with each “2nd” edition is: “What I can expect if I already bought the 1st one?”. This edition contains all the recipes from the 1st edition updated to the new Delphi 10.1 Berlin, plus a lot (ca 150 pages) of brand new contents. There is also a brand new chapter about less-known RTL classes. Also some “old” recipes has been completely rewritten because some techniques has been superseded by the newer Delphi versions. So, if you liked the 1st edition, you should find something interesting also in the 2nd one. The 2nd edition contains 470 pages compared to the 328 of the 1st edition.

Topics of the book

  • Understand the basics of professionals Delphi programming
  • Become a Delphi language Ninja
  • Knowing the new RTL classes to work with HTTP/S, Net encodings, event bus, compression etc.
  • Develop visually stunning applications using FireMonkey
  • Deploy LiveBinding effectively with the right OOP approach
  • The thousand faces of multithreading: syncronization tecniques in the real world
  • The Parallel Programming Library: Tasks, Futures parallel For
  • Create server-side programs to serve RESTful web services and provide data to your mobile apps
  • Use well-defined GUI design patterns to build mobile applications that provide a great user experience
  • Build mobile apps that read data from a remote server efficiently
  • Using sensors and network in mobile apps
  • Call the platform native API on Android and iOS even for an unpublished API
  • Manage software customization for your customer by making better use of an extended RTTI
  • Implement the most popular design pattern without wasting too much time on debugging and bug fixing

Some considerations

Delphi Cookbook 2nd edition, just like to 1st one, it is not an introductory book, you will not find any “Introduction to the Object Pascal language”, however the majority of the chapters are not too complex and can be grasped also by the new Delphi programmers.

Where to buy

The book is available for sale on the editor website and on Amazon.

PacktPub (Official book page)

https://www.packtpub.com/application-development/delphi-cookbook-second-edition

Amazon

Delphi Cookbook 2nd Edition on Amazon

 

Table of contents

Chapter 1: DELPHI BASICS

  • Change your application look&feel with VCL styles and no code
  • Changing the style of your application at run time
  • Customizing TDBGrid
  • Using owner draw combos and listboxes
  • How to make an owner draw control aware of the VCL styles
  • Creating a stack of embedded forms
  • Manipulating JSON
  • Manipulating and transform XML documents
  • I/O in the 21th century: knowing the streams
  • Creating a Windows service
  • Associating a file extension with your application on Windows
  • Be coerent with the Windows look&feel using TTaskDialog

Chapter 2: BECOME A DELPHI LANGUAGE NINJA

  • Fun with anonimous methods – using higher-Order functions
  • Writing enumerable types
  • RTTI to the rescue – configuring your class at runtime
  • Duck typing using RTTI
  • Creating helpers for your classes

Chapter 3: KNOWING YOUR FRIENDS: THE DELPHI RTL

  • Check strings with regular expressions
  • Consuming RESTful services using native HTTP(S) client libraries
  • Cope with the encoded Internet world using System.NetEncodings
  • Save space using System.Zip
  • Decouple your code using a cross platform publish/subscribe mechanism

Chapter 4: GOING CROSS PLATFORM WITH FIREMONKEY

  • Giving a new appearance to the standard FireMonkey controls using styles
  • Creating a styled TListBox
  • Impressing your clients with animations
  • Using master/details with LiveBindings
  • Showing complex vector shapes using Paths
  • Using Firemonkey in a VCL application
  • Reinvent your GUI a.k.a Mastering Firemonkey controls, shapes and effects

Chapter 5: THE THOUSAND FACES OF MULTITHREADING

  • Synchronizing shared resources with TMonitor
  • Talking with main thread using a thread safe queue
  • Synchronizing multiple threads using TEvent
  • Displaying a measure on 2D graph like an oscilloscope
  • Using the Parallel Programming Library in the real world: Tasks
  • Using the Parallel Programming Library in the real world: Futures
  • Using the Parallel Programming Library in the real world: Parallel For/Join

Chapter 6: PUT DELPHI ON THE SERVER

  • Developing web client JavaScript applications with WebBroker on the server
  • Converting a console service application to Windows service
  • Serializing a dataset to JSON and back
  • Serializing objects to JSON and back using RTTI
  • Sending a POST HTTP request encoding parameters
  • Implementing a RESTful interface using WebBroker
  • Controlling remote application using UDP
  • Using AppTethering to create companion app
  • Creating DataSnap Apache modules
  • Creating WebBroker Apache modules
  • Using native HTTP(S) client libraries

Chapter 7: RIDE THE MOBILE REVOLUTION WITH FIREMONKEY

  • Taking a photo, applying effects, and sharing it
  • Using ListView to show and search local data
  • Using SQLite databases to handle a to-do list
  • Do not block the main thread!
  • Using a styled TListView to handle long list of data
  • Customizing the TListView
  • Taking a photo and location and sending it to a server continuously
  • Talking with the backend
  • Making a phone call from your app!
  • Tracking the application’s lifecycle

Chapter 8: USING SPECIFIC PLATFORM FEATURES

  • Using Android SDK Java classes
  • Using iOS SDK classes
  • Displaying PDF files in your app
  • Sending Android intents
  • Letting your phone talk: using the Android TextToSpeech engine
  • Using Java classes in Android apps with Java2OP
  • Do it in background, the right way: Android services

Events

In the next months there will be some events regarding the book.

  1. A one day workshop, held in Rome and Milan, about selected recipes of the books with additional contents and other “live” considerations.
  2. Some blog post about contents that not fitted (by time and other contraints) in the book. Most of them will be about the server side development and will involve Redis and other open source projects.
  3. Oct 6,7 2016 PacktPub will be one of the sponsor of ITDevCon 2016. During that event there will be some surprises for the attendants offered by the Delphi Cookbook “series” (yes, 2 is a series 🙂 ) editor.

 

Conclusions

As usual, writing a tech book is an hard task. 470 pages are more than I was thinking at the day 0. However, I’m quite (not completely, as usual) satisfied about the work. I really hope that you will enjoy the content at least as much I enjoy the writing.

A Simple start with MVP in Delphi for Win32, Part 2

Some month ago I wrote a simple article about an MVP variant called PassiveView.
That example was very simple. Now I’ll present a more “advanced” version of that example.

The main problem with first example was the following method:

procedure TfrmCalculatorView.FormCreate(Sender: TObject);
begin
  //Link controls with related interface
  IFirstOperand := TGUIEdit.Create(EditFirstOp);
  ISecondOperand := TGUIEdit.Create(EditSecondOp);
  ICalcResult := TGUIEdit.Create(EditResult);
  IOperators := TGUISelectableList.Create(ComboOperators);
  IError := TGUIEdit.Create(EditError);

  //link view and presenter
  FPresenter := TCalculatorPresenter.Create(Self); //<<-- THIS IS THE BAD LINE
end;

The “BAD” line links the View with the Presenter but it’s in the view code, so this is meaning that View KNOWS the presenter… and this is not a good thing becouse the view is not so “passive”.

In a more advanced (and complex) version the View should be completely ignorant about the class that implement the presenter and the service.

In the main dpr file now the code now looks like the following.

var
  MainPresenter: ICalculatorPresenter;
  CalculatorView: TForm;
begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  //SETUP THE MAIN APPLICATION FORM FOR VCL PURPOSE
  Application.CreateForm(TfrmCalculatorView, CalculatorView);  
  //SETUP ALL THE LINKS BETWEEN THE MVP TRIAD
  MainPresenter := TCalculatorPresenter.Create(CalculatorView as ICalculatorView, TCalculatorService.Create);
  //LETS START!
  Application.Run;
end.

Now the presenter take care about all links between the MVP triad.

constructor TCalculatorPresenter.Create(CalculatorView: ICalculatorView;
  CalculatorService: ICalculatorService);
begin
  inherited Create;
  FCalculatorService := CalculatorService;
  FCalculatorView := CalculatorView;
  FCalculatorView.SetPresenter(self);
  InitView;  //does the links
end;

There is another addition to the previous example. Now there is only one constructor in the presenter, and using dependency injection take 2 interface for the view and the service.

    constructor Create(CalculatorView: ICalculatorView; CalculatorService: ICalculatorService);

Another plus is the possibility to open the same form a number of times without change the code for create it.

This is the GUI for this simple application.

3 instance of the same view with different presenter and service
3 instance of the same view with different presenter and service

As bonus, unit tests and mock object arent changed.

As usual the source code is here.

A Simple start with MVP in Delphi for Win32, Part 1

As GUI framework such as VCL become more and more powerful, it’s common practice to let the UI layer do more than it should. Without a clear separation of responsibilities, the UI layer can often become an integral part of application and businness logic, but… this kind of responsabilities belongs to other layers of the application.
A design pattern (and his numberless variants), is especially well suited to solving this problem.

In this article I want to build a simple application using MVP pattern. Actually, pattern used is not “clear” MVP but his variation called Passive View.

Using Fowler words:

A perennial problem with building rich client systems is the complication of testing them. Most rich client frameworks were not built with automated testing in mind. Controlling these frameworks programaticly is often very difficult.

A Passive View handles this by reducing the behavior of the UI components to the absolute minimum by using a controller that not just handles responses to user events, but also does all the updating of the view. This allows testing to be focused on the controller with little risk of problems in the view.

Passive View ensures no dependecies between Model and View.

Passive View has no dependencies between view and model (Unlike most MVC-style triad)
Passive View has no dependencies between view and model (Unlike most MVC-style triad)

In this sample, “model” is a simple layer for application logic. In real world, “service layer” should incapsulate “application service” and “domain model“.

Application looks like following:

The Calculator
The Calculator
Div operator with result
Div operator with result
Div operator with a EDivByZero Exception
Div operator with a EDivByZero Exception

Connect View and Presenter
The view (the Form in VCL application) must implement an interface.

This interface should provide all method to interact with GUI:

ICalculatorView = interface
  ['{471E3657-C6CE-49A3-BCB4-8FA6AF611DAD}']
  function FirstOperand: String;
  function SecondOperand: String;
  procedure SetFirstOperand(Value :String);
  procedure SetSecondOperand(Value :String);
  function GetOperator: IGUISelectableList;
  procedure SetCalcResult(const Value: String);
  procedure SetCalcResultReadOnly(const Value: Boolean);
  function Error: IGUIEdit;
end;

For simple interacting with GUI widget (in our example are EditFirstOperand, EditSecondoperand and EditCalcResult) we use a simple methods like following

  function FirstOperand: String;
  function SecondOperand: String;
  procedure SetFirstOperand(Value :String);
  procedure SetSecondOperand(Value :String);

But, if we need more by our widget (like populating combo box or change font color in the EditError or set ReadOnly to true) we should use another interface for a family of component.
In this sample I wrote 3 general interface:

  IGUIBaseInterface = interface
    ['{F0B7F031-9302-415E-8545-1FE20A365840}']
  end;

  IGUIEdit = interface(IGUIBaseInterface)
    ['{FE2D56FB-0CFB-4B33-9B56-0A523B235D37}']
    procedure SetText(const Value: String);
    function GetText: String;
    function GetAsInteger: Integer;
    function GetAsFloat: Extended;
    procedure SetReadOnly(const AValue: boolean);
    procedure SetVisible(const Value: Boolean);
    function GetTextAsInteger: Integer;
    procedure SetTextAsinteger(const Value: Integer);
    function GetTextAsFloat: Extended;
  end;

  IGUISelectableList = interface(IGUIBaseInterface)
    ['{EEFE5C52-94C3-464B-80F2-05E443B0F0F6}']
    procedure SetText(const Value: String);
    function GetText: String;
    procedure SetValue(const Value: String);
    function GetValue: String;
    function GetSelected: ISSKeyValue;
    procedure AddPair(AKey, AValue: String);
    procedure Clear;
  end;

For implementation details see attached sample code.

Finally in FormCreate of our form we can wire Presenter and View:

TfrmCalculatorView = class(TForm, ICalculatorView)
  //code 
end;
  //interface section
procedure TfrmCalculatorView.FormCreate(Sender: TObject);
begin
  //Link controls with related interface
  IOperators := TGUISelectableList.Create(ComboOperators);
  IError := TGUIEdit.Create(EditError);

  //link view and presenter
  //In this version VIEW know PRESENTER
  FPresenter := TCalculatorPresenter.Create(Self);
end;

This is a very simple example, so not all looks like real world. In a real world application, for example, view should not known the presenter class. With dependency injection you can do that (Next article in this serie will talk about this).

Every event generated by View (our Form) must be redirected to Presenter.

procedure TfrmCalculatorView.Button1Click(Sender: TObject);
begin
  FPresenter.DoCalc;
end;

Another approach is to publish some events in view interface and let presenter to bind them via standard event handler or anonimous methods (but this is for another post).

In attached sample code there is a sample application and unit test for Service Layer and View.
Required Mock Library is included in the zip file.

Simple Passive View, Sample Code

In 2nd part I’ll talk about unit test and mock object in Passive View.

.NET databinding in Delphi for Win32

Databinding is defined as: “General technique that binds two data/information sources together and maintains them in sync. This is usually done with two data/information sources with different types as in XML data binding. However in UI data binding, we bind data and information objects of the same type together (e.g. Java objects to Java UI elements).”

Databinding is common technique in VCL. Since Delphi 1 we have TDataset class for bind data and UI controls (DB Aware) in a GUI application.

In .NET world, instead, databinding is very different.

So, I’m starting to write (actually for fun) a DataBinder component to use .NET “like” databinding (or something similar to) in Delphi for Win32 too.

All the code has been written in about 2 hours.

TDataBinder

With this component you can “bind” an object property to another object property in a declarative mode.

e.g.

DataBinder.Add(Person, 'FirstName', Edit1, 'Text');

and then, every update to Person.FirstName property, will be reflected in the Edit1.Text property.

You can bind different control properties to different BO properties.

e.g.

//Text = FirstName
DataBinder.Add(Person, 'FirstName', Edit1, 'Text');
//If Person is not married, TEdit become flat
DataBinder.Add(Person, 'IsMarried', Edit1, 'Ctl3D');

So in your initialization code (e.g. FormCreate) you can write somethig similat to following:

procedure TForm3.FormCreate(Sender: TObject);
var
binder: TDataBinder;
begin
//Create your "BO"
Person := TPerson.Create;
//read data from "database"
Person.Load;

//Setup databinding...
binder := TDataBinder.Create(self);
binder.Add(Person, 'FirstName'   ,      Edit1,     'Text');
binder.Add(Person, 'LastName',          Edit2,     'Text');

//The same attribute binded to 3 controls
binder.Add(Person, 'Married',     CheckBox1, 'Checked');
binder.Add(Person, 'Married'   , Edit1,     'Ctl3D');
binder.Add(Person, 'Married',     Edit2,     'Ctl3D');

//The same attribute binded to 2 controls
binder.Add(Person, 'SomeInteger', ComboBox1, 'ItemIndex');
binder.Add(Person, 'SomeInteger',     TrackBar1, 'Position');

//A derived property
binder.Add(Person, 'FullName',     Panel1, 'Caption');

//let start...
binder.Bind;
end;

Other info asap so, stay tuned.

Download Code and compiled sample

(Source code require Delphi 2009)