41,99 €
Quickly learn and employ practical recipes for developing real-world, cross-platform applications using Delphi.
Key Features
Book Description
Delphi is a cross-platform integrated development environment (IDE) that supports rapid application development on different platforms, saving you the pain of wandering amid GUI widget details or having to tackle inter-platform incompatibilities.
Delphi Cookbook begins with the basics of Delphi and gets you acquainted with JSON format strings, XSLT transformations, Unicode encodings, and various types of streams. You’ll then move on to more advanced topics such as developing higher-order functions and using enumerators and run-time type information (RTTI). As you make your way through the chapters, you’ll understand Delphi RTL functions, use FireMonkey in a VCL application, and cover topics such as multithreading, using aparallel programming library and deploying Delphi on a server. You’ll take a look at the new feature of WebBroker Apache modules, join the mobile revolution with FireMonkey, and learn to build data-driven mobile user interfaces using the FireDAC database access framework. This book will also show you how to integrate your apps with Internet of Things (IoT).
By the end of the book, you will have become proficient in Delphi by exploring its different aspects such as building cross-platforms and mobile applications, designing server-side programs, and integrating these programs with IoT.
What you will learn
Who this book is for
Delphi Cookbook is for intermediate developers with a basic knowledge of Delphi who want to discover and understand all the development possibilities offered by it.
Daniele Spinetti is a software architect living in Rome. He is an Embarcadero MVP. Delphi/Object Pascal is his favorite tool/programming language, and he is a lead and active member of several projects in the open source community. In his tutoring activities (conferences and training), he likes to talk about innovative topics in software architectures. He's a huge fan of design patterns and TDD. Daniele Teti is a software architect, trainer, and consultant with over 20 years of experience. He drives the development of the most popular Delphi open source project on GitHub—DelphiMVCFramework. He's also a huge fan of design patterns, machine learning, and AI. Daniele is the CEO of BIT Time Professionals, an Italian company specializing in high-level consultancy, training, development, and machine learning systems.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 653
Veröffentlichungsjahr: 2018
Copyright © 2018 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Merint MathewAcquisition Editor: Alok DhuriContent Development Editor: Priyanka SawantTechnical Editor: Ruvika RaoCopy Editor: Safis EditingProject Coordinator: Vaidehi SawantProofreader: Safis EditingIndexer: Tejal Daruwale SoniGraphics: Jason MonteiroProduction Coordinator: Shraddha Falebhai
First published: September 2014 Second edition: June 2016 Third edition: July 2018
Production reference: 1310718
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78862-130-4
www.packtpub.com
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Daniele Spinetti is a software architect living in Rome. He is an Embarcadero MVP. Delphi/Object Pascal is his favorite tool/programming language, and he is a lead and active member of several projects in the open source community. In his tutoring activities (conferences and training), he likes to talk about innovative topics in software architectures. He's a huge fan of design patterns and TDD.
Daniele Teti is a software architect, trainer, and consultant with over 20 years of experience. He drives the development of the most popular Delphi open source project on GitHub—DelphiMVCFramework. He's also a huge fan of design patterns, machine learning, and AI. Daniele is the CEO of BIT Time Professionals, an Italian company specializing in high-level consultancy, training, development, and machine learning systems.
Primož Gabrijelčič started coding in Pascal on 8-bit micros in the 1980s, and he never looked back. In the last 20 years, he was mostly programming high-availability server applications used in the broadcasting industry. He's also an avid writer and has written several hundred articles, and he is a frequent speaker at Delphi conferences, where he likes to talk about complicated topics, ranging from memory management to creating custom compilers.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
Delphi Cookbook Third Edition
Packt Upsell
Why subscribe?
PacktPub.com
Contributors
About the authors
About the reviewer
Packt is searching for authors like you
Dedication
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Conventions used
Sections
Getting ready
How to do it…
How it works…
There's more…
See also
Get in touch
Reviews
Delphi Basics
Introduction
Changing your application's look and feel with VCL styles
Getting ready
How to do it...
How it works...
There's more...
Changing the style of your VCL application at runtime
Getting ready
How to do it...
How it works...
There's more...
Customizing TDBGrid
Getting ready
How to do it...
How it works...
There's more...
Using owner-draw combos and listboxes
Getting ready
How to do it...
How it works...
There's more...
Making an owner-draw control aware of the VCL styles
Getting ready
How it works...
There's more...
Creating a stack of embedded forms
Getting ready
How it works...
There's more...
Manipulating JSON
Getting ready
How to do it...
There's more...
Manipulating and transforming XML documents
Getting ready
How to do it...
How it works...
There's more...
I/O in the 21st century – knowing the streams
Getting ready
How it works...
There's more...
Creating a Windows Service
Getting ready
How it works...
There's more...
Using the TService.LogMessage method
Associating a file extension with your application on Windows
Getting ready
How to do it...
There's more...
Be coherent with the Windows look and feel using TTaskDialog
Getting started
How it works...
There's more...
The amazing TFDTable – indices, aggregations, views, and SQL
Getting ready
How to do it...
How it works...
There's more...
ETL made easy – TFDBatchMode
Getting ready
How to do it...
How it works...
There's more...
Data integration made easy – TFDLocalSQL
Getting ready
How to do it...
How it works...
There's more...
See also
Becoming a Delphi Language Ninja
Introduction
Fun with anonymous methods – using higher-order functions
Getting ready
How to do it...
There's more...
Writing enumerable types
Getting ready
How to do it...
There's more...
See also
Using enumerable types to create new language features
Getting ready
How to do it...
How it works...
There's more...
RTTI to the rescue – configuring your class at runtime
Getting ready
How to do it...
There's more...
See also
Duck typing using RTTI
Getting ready
How to do it...
There's more...
BOs validation using RTTI attributes
Getting ready
How to do it...
How it works...
There's more...
Bonus recipe – Validation using RTTI attributes
See also...
Creating helpers for your classes
Getting ready
How to do it...
There's more...
Knowing Your Friends – The Delphi RTL
Introduction
Checking strings with regular expressions
Getting ready
How to do it...
There's more...
Consuming RESTful services using native HTTP(S) client libraries
Getting ready
Some HTTP considerations
How it works...
There's more...
THTTPClient's methods which directly map HTTP verbs
How to verify that HTTP TRACE is disabled
Coping with the encoded internet world using System.NetEncodings
Getting ready
How it works...
There's more...
Saving space using System.Zip
How it works...
There's more...
Decoupling your code using a cross-platform publish/subscribe mechanism
Getting ready...
How it works...
There's more...
Going Cross-Platform with FireMonkey
Introduction
Giving a new appearance to the standard FireMonkey controls using styles
Getting ready
How to do it...
How it works...
See also
Creating a styled TListBox
Getting ready
How to do it...
How it works...
See also
Impressing your clients with animations
How to do it...
How it works...
See also
Using master/details with LiveBindings
Getting ready
How to do it...
How it works...
There's more...
See also
Showing complex vector shapes using paths
Getting ready
How to do it...
How it works...
There's more...
Using FireMonkey in a VCL application
How to do it...
How it works...
There's more...
Reinventing your GUI, also known as mastering Firemonkey controls, shapes, and effects
Getting ready
How it works...
There's more...
The Thousand Faces of Multithreading
Introduction
Synchronizing shared resources with TMonitor
Getting ready
How to do it...
How it works...
There's more...
Talking with the main thread using a thread-safe queue
Getting ready
How to do it...
There's more...
Synchronizing multiple threads using TEvent
Getting ready
How to do it...
There's more...
Bonus recipe – AsyncTaskTests
Communication made easy with Delphi Event Bus
Getting ready
How to do it...
How it works...
There's more...
See also
Displaying a measure on a 2D graph like an oscilloscope
Getting ready
How to do it...
There's more...
Using the Parallel Programming Library in the real world: Tasks
Getting ready
How it works...
There's more...
Using the Parallel Programming Library in the real world: Futures
Getting ready
How it works...
There's more...
Using the Parallel Programming Library in the real world: Parallel For/Join
Getting ready
How it works...
There's more...
Putting Delphi on the Server
Introduction
Developing web client JavaScript applications with WebBroker on the server
Getting ready
How it works...
Retrieving the people list
Creating or updating a person
Running the application
There's more...
Converting a console application into a Windows service
Getting ready
How to do it...
How it works...
There's more...
Serializing a dataset to JSON and back
Getting ready
How it works...
There's more...
Serializing objects to JSON and back using RTTI
Getting ready
How to do it...
How it works...
There's more...
Sending a POST HTTP request for encoding parameters
Getting ready
How to do it...
How it works...
There's more...
Implementing a RESTful interface using WebBroker
Getting ready
How to do it...
How it works...
There's more...
Controlling the remote application using UDP
Getting ready
How to do it...
How it works...
There's more...
Using app tethering to create a companion app
Getting ready
How it works...
There's more...
Creating DataSnap Apache modules
Getting ready
How to do it...
How it works...
There's more...
Creating WebBroker Apache modules
Getting ready
How to do it...
How it works...
There's more...
Using native HTTP(S) client libraries
Getting ready
How it works...
There's more...
Logging like a pro using LoggerPro
Getting ready
How to do it...
How it works...
There's more...
See also
Linux Development
Introduction
Creating Linux TCP/IP servers
Getting ready
How to do it...
How it works...
There's more...
How to correctly handle Linux signals
Getting ready
How to do it...
How it works...
There's more...
See also
How to build a modern Linux daemon
Getting ready
How to do it...
How it works...
There's more...
systemd
See also
Building a TCP/IP Linux server and daemonizing it
Getting ready
How to do it...
How it works...
There's more...
Building a RESTFul server for Linux
Getting ready
How to do it...
How it works...
There's more...
Building a complete RESTful server with database access and web client interface
Getting ready
How to do it...
How it works...
There's more...
See also
Creating WebBroker Apache modules for Linux
Getting ready
How to do it...
How it works...
There's more...
See also
Riding the Mobile Revolution with FireMonkey
Introduction
Taking a photo, applying effects, and sharing it
Getting ready
How to do it...
How it works...
There's more...
Using TListView to show and search local data
Getting ready
How to do it...
How it works...
There's more...
Using SQLite databases to handle a to-do list
Getting ready
How to do it...
There's more...
Do not block the main thread!
Getting ready
How to do it...
How it works...
There's more...
Using a styled TListView to handle a long list of data
Getting ready
How to do it...
How it works...
There's more...
Customizing the TListView
Getting ready
How it works
There's more...
Taking a photo and location and sending it to a server continuously
Getting ready
How to do it...
The client side
The server side
There's more...
Talking with the backend
Getting ready
How to do it...
There's more...
Making a phone call from your app
Getting ready
How to do it...
How it works...
There's more...
Tracking the application's life cycle
Getting ready
How to do it...
There's more...
Building your own SMS sending service with the REST API
Getting ready
REST server
Mobile sending application
How it works...
There's more...
Using specific platform features
Introduction
Using Android SDK Java classes
Getting ready
How to do it...
There's more...
Using iOS Objective-C SDK classes
Getting ready
How it works...
There's more...
Displaying PDF files in your app
Getting ready
How it works...
Showing the PDF file on Android
Showing the PDF file on iOS
There's more...
Downloading the PDF file from the server
Sending Android Intents
Getting ready
How it works...
More complex intent – sending a full flagged email
Starting an activity for a result – the SpeechToText engine
There's more...
Letting your phone talk – using the Android TextToSpeech engine
Getting ready
How it works...
There's more...
Using Java classes in Android apps with Java2OP
Getting ready
How to do it...
There's more...
Doing it in the background, the right way – Android services
Getting ready
How it works...
There's more...
Delphi and IoT
Introduction
Prerequisites
Arduino
Raspberry Pi
Arduino versus Raspberry Pi
How to blink an LED using Arduino
Getting ready
How to do it...
How it works...
There's more...
See also
How to drive multiple relays with Arduino and Delphi
Getting ready
How to do it...
How it works...
There's more...
See also
Reading data from Arduino
Getting ready
How to do it...
How it works...
How to blink an LED using Raspberry Pi
Getting ready
How to do it...
How it works...
See also
How to drive multiple relays with Raspberry Pi and Delphi
Getting ready
How to do it...
How it works...
Reading data from Raspberry PI
Getting ready
How to do it...
How it works...
Other Books You May Enjoy
Leave a review - let other readers know what you think
If you've been a software developer for a long time, you certainly know how useful a conversation can be with a colleague who has already done something similar to what you are doing and can explain it, as they will have faced the same problem. It is not possible to put all the possible situations that a developer can face in a book, but many problems are similar, at least in principle. This is the reason this book is organized as a cookbook: just like a combination of foods can be adapted and modified to be appropriate for different types of dinner, a programming recipe can provide the idea to solve many different problems. This book is an advanced guide that will help Delphi developers get more skilled in their everyday job. The everyday job, and the quality of your deliverables, is what is contributing to the quality of your professional life. If it does not make sense, reinventing the wheel repeatedly, especially when working with a well-established tool, such as Delphi. The focus of the book is to provide readers with comprehensive and detailed examples on how effectively the Delphi software can be designed and written. All the recipes in the book are the result of years of development, training, and consultancy activities in many different fields of IT, from small systems with thousands of installations to large systems commissioned by big companies or by governments. It is not a magic book that will solve all your development problems (if you find it, tell me, please!), but it could be helpful to get a different point of view on a specific problem, or a hint on how to solve problems. Armed with the knowledge of advanced concepts, such as high-order functions and anonymous methods, generics and enumerable, extended RTTI and duck typing, LiveBindings, multi-threading, FireMonkey, mobile development, server-side development, and IoT, you will be pleasantly surprised how quickly and easily you can use Delphi to write high-quality, clean, readable, fast, maintainable, and extensible code. I read too many boring programming books, so I tried to maintain a relaxed and light exposition. A small applicability scenario that describes a situation where a particular technology, approach, or design pattern can be used successfully introduces all the recipes. The recipes are not very complex, because otherwise the book may become thousands of pages long, but also not trivial, because the IT books landscape is already full of simple examples with few direct applicabilities. I tried to do a good tradeoff, and I hope to be able to do it. Every time I start reading a new book, I ask myself, Will the author have something interesting to say?, How much will this book change my point of view about the topics mentioned?, Is it worth the time spent to read it? Now, in spite of being from the other side of the river, I worked harder to put as much good quality contents in my books as possible; I hope that will match your expectations. One last note: writing hundreds of pages about advanced programming is not an easy task. However, I am very pleased to have done it, and I hope you will enjoy reading it at least as much as I enjoyed writing it.
In this third edition, the book still respects the structure and the style previously applied, which Daniele Teti explains perfectly in his preface. I just want to add that this approach is the best method for learning: a minimum of theory to understand the topic and a pragmatic approach with the resolution of a real problem so that the reader can have practical feedback and see it implemented.
This book aims to help professional Delphi developers in their day-to-day job. This book will teach you about the newest Delphi technologies and its hidden gems. It is not a book for a newbie, but the practical approach will help you reach a new level with your Delphi skills. The experienced developer can benefit from this book, because non-trivial problems are solved using best practices. Where more than one way is available or the topic is too broad to be explained in the available pages, references are provided to allow you to go deeper into that field. It is a book to have on your desk for the next few years.
Chapter 1, Delphi Basics, talks about a set of general approaches that should not be ignored by any Delphi programmer. Some topics are simple and immediate and some are not, but all of them should be well understood. By the end of this chapter, the reader is able to use some of the fundamental Delphi techniques related to RTL, VCL, and OS integration.
Chapter 2, Becoming a Delphi Language Ninja, focuses on the Object Pascal language. The programming language is the way you talk to the machine, so you must be fluent and know all the possibilities offered. This chapter talks about higher-order functions, practical utilization of the extended RTTI, regular expressions, and other things useful to augment the power of your code and to lower the amount of time spent on debugging.
Chapter 3, Knowing Your Friends – The Delphi RTL, focuses on the Delphi's RTL. There isn't a detailed description of all the Delphi's RTLs (you would need 10 books like this one, which would be particularly boring, I guess), but you can find some recipes that explain some of the most important RTL features and some less known but really useful classes. You'll learn how to use regular expressions, the most popular encoding format used by HTTP base applications, and how to use the built-in data de/compression-related classes.
Chapter 4, Going Cross-Platform with FireMonkey, is dedicated to the FireMonkey framework in general. What you will learn from this chapter can be used in many of the platforms that FireMonkey supports. Moreover, you will learn about non-trivial LiveBindings utilizations.
Chapter 5, The Thousand Faces of Multithreading, talks about thread synchronization and the mechanisms used to obtain this synchronization, such as TMonitor, thread-safe queues, and TEvent. It is also one of the most complex chapters. By the end of this chapter, the reader will be able to create and communicate with background threads, leaving your main thread free to update your GUI (or to communicate with the OS).
Chapter 6, Putting Delphi on the Server, focuses on how well Delphi can behave when running on a server. Some people think that Delphi is a client-only tool, but that's not true. In this chapter, we'll show you how to create powerful servers that offer services over a network. We'll also implement a JavaScript client that brings the database data into the user browser. The techniques explained in this chapter open a range of possibilities, especially in the mobile and web area.
Chapter 7, Linux Development, is dedicated to development with Delphi on the most commonly-used operating system for server environments—Linux. This chapter covers several key points about Linux development: from the foundation, such as handling signals, forking, and daemonizing processes to the construction of RESTFul Server with database access and JavaScript client.
Chapter 8, Riding the Mobile Revolution with FireMonkey, explores the mobile development with Delphi and FireMonkey. If you are interested in mobile development, I think that will be your favorite chapter! Mobile is everywhere, and this chapter will explain how to write software for your Android or iOS device, what are the best practices to use, how to save your data on the mobile, how to retrieve and update remote data, and how to integrate with the mobile operating system.
Chapter 9, Using Specific Platform Features, shows you how to integrate your app with the underlying mobile operating systems beyond what FireMonkey offers. You will learn how to import Java and Objective C libraries in your app and how to use the SDK classes from your Object Pascal code.
Chapter 10, Delphi and IoT, talks about how the two most popular boards on the market—Arduino and Raspberry Pi—can interact with Delphi. You will learn how a Delphi application can control them, how can you control the components associated with them and recover data that they hold. The approach and techniques explained in this chapter open Delphi to IoT.
This book talks about Delphi, so you need it. Not all the recipes are available in all the Delphi editions. Most of the projects, including the mobile, can be compiled with Delphi Community Edition or Professional (depending on license term) and higher, while for some server development parts, especially Linux, the Architect or Enterprise version is required. All the projects are compiled and tested with the latest Delphi version at the time of writing, but many recipes can also be compiled on older versions.
If you want to run the mobile app on a phone or a tablet, you can use the Android emulator or the iOS simulator, but we strongly suggest an actual device to see how the app really behaves. To deploy an iOS app on your device, you also need an Apple computer with MacOSX. For the development with Linux, a machine (also a Virtual Machine is okay) with the Linux OS is necessary to be installed, and for the IoT section, the reference boards are Arduino and Raspberry Pi.
You can download the example code files for this book from your account at www.packtpub.com. If you purchased this book elsewhere, you can visit www.packtpub.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packtpub.com
.
Select the
SUPPORT
tab.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latestversion of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub athttps://github.com/PacktPublishing/Delphi-Cookbook-Third-Edition. We also have other code bundles from our rich catalog of books and videos available athttps://github.com/PacktPublishing/. Check them out!
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/DelphiCookbookThirdEdition_ColorImages.pdf.
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "When we selected the Iceberg Classico style as the default style, the Delphi IDE added a line just before the creation of the main form, setting the default style for all the applications using TStyleManager.TrySetStyle static methods."
A block of code is set as follows:
begin
Application.Initialize; Application.MainFormOnTaskbar := True;
TStyleManager.TrySetStyle('Iceberg Classico');
Application.CreateForm(TMainForm, MainForm); Application.Run;
end
Any command-line input or output is written as follows:
$ systemctl disable unit
Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "If you want to open a separate Terminal window for running and debugging your application, you have to enable the Use Launcher Application checkbox (you can find it in Project | Options | Debugger)."
In this book, you will find several headings that appear frequently (Getting ready,How to do it..., How it works..., There's more..., and Seealso).
To give clear instructions on how to complete a recipe, use these sections as follows:
This section tells you what to expect in the recipe and describes how to set up any software or anypreliminary settings required for the recipe.
This section contains the steps required to follow the recipe.
This section usually consists of a detailed explanation of what happened in the previous section.
This section consists of additional information about the recipe in order to make you moreknowledgeable about the recipe.
This section provides helpful links to other useful information for the recipe.
Feedback from our readers is always welcome.
General feedback: Email [email protected] and mention the book title in the subject of your message. If you have questions about any aspect of this book, please email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packtpub.com.
In this chapter, we will cover the following recipes:
Changing your application's look and feel with VCL styles and without any code
Changing the style of your application at runtime
Customizing TDBGrid
Using owner-draw combos and listboxes
Making an owner-draw control aware of the VCL styles
Creating a stack of embedded forms
Manipulating JSON
Manipulating and transforming XML documents
I/O in the 21st century—knowing the streams
Creating a Windows Service
Associating a file extension with your application on Windows
Being coherent with the Windows look and feel using TTaskDialog
The amazing TFDTable—indices, aggregations, views, and SQL
ETL made easy—TFDBatchMode
Data integration made easy—TFDLocalSQL
This chapter will explain some of the day-to-day needs of a Delphi programmer. These are ready-to-use recipes that will be useful every day and have been selected ahead of others because, although they may be obvious for some experienced users, they are still very useful. Even if there isn't any specific database-related code, many of the recipes can be used when you are dealing with data.
Visual ComponentLibrary (VCL) styles are a major new entry in the latest versions of Delphi. They were introduced in Delphi XE2 and are still one of the lesser-known features for good old Delphi developers. However, as business people say, looks matter, so the look and feel of your application could be one of the reasons to choose your product over another from a competitor. Consider that, with a few mouse clicks, you can apply many different styles to your application to change the look and feel of it. So, why not to give it a try?
VCL styles can be used to revamp an old application or to create a new one with a non-standard GUI. VCL styles are a completely different beast to FireMonkey styles. They are both styles, but with completely different approaches and behaviors.
To get started with VCL styles, we'll use a new application. So, let's create a new VCL application and drag and drop some components onto the main form (for example, two TButton controls, one TListBox, one TComboBox, and a couple of TCheckBox).
You can now see the resulting form that is running on my Windows 10 machine:
Now, we've got to apply a set of nice styles by following these steps:
Go to
Project
|
Options
from the menu. Then, in the resultant dialog, go to
Application
|
Appearance
and select all the styles that we want to include in our application.
If you use the
Preview
button, the IDE shows a simple demo form with some controls, and we can get an idea about the final result of our styled form. Feel free to experiment and choose the style or set of styles that you like. Only one style at a time can be used, but we can link the necessary resources inside the executable and select the proper one at runtime.
After selecting all the required styles from the list, we've got to select one in the combobox at the bottom. This style will be the default style for our form and it will be loaded as soon as the application starts. You can delay this choice and make it at runtime using code, if you prefer.
Click on
OK
, hit
F9
(or go to
Run
|
Run
), and your application will be styled:
Selecting one or more styles from Project | Options | Application | Appearance will cause the Delphi linker to link the style resource into your executable. It is possible to link many styles into your executable, but you can use only one style at a time. So, how does Delphi know which style you want to use when there are more than one? If you check the Project file (the file with the .dpr extension) by going to Project | View Source Menu (for shortcut lovers, Ctrl + V with the project selected in Project Manager), you can see where and how this little bit of magic happens.
The following lines are the interesting section:
begin
Application.Initialize; Application.MainFormOnTaskbar := True;
TStyleManager.TrySetStyle('Iceberg Classico');
Application.CreateForm(TMainForm, MainForm); Application.Run;
end
When we selected the Iceberg Classico style as the default style, the Delphi IDE added a line just before the creation of the main form, setting the default style for all the applications using TStyleManager.TrySetStyle static methods.
TStyleManager is a very important class when you deal with VCL styles. We'll see more about it in an upcoming recipe, where you'll learn how to change styles at runtime.
Delphi and C++Builder 10.2 Tokyo come with 39 VCL Styles available in the folder (with a standard installation) at C:\Program Files (x86)\Embarcadero\Studio\19.0\Redist\styles\vcl\.
Embarcadero provides an additional eight premium styles that are available in the VCL premium style pack: https://cc.embarcadero.com/item/30492.
Moreover, it is possible to create your own styles or modify existing ones using the Bitmap Style Designer. You can access it by going to Tools | Bitmap Style Designer Menu.
For more details on how to create or customize a VCL style, visit http://docwiki.embarcadero.com/RADStudio/en/Creating_a_Style_using_the_Bitmap_Style_Designer.
The Bitmap Style Designer also provides test applications to test VCL styles.
VCL Styles are a powerful way to change the appearance of your application. One of the main features of VCL styles is the ability to change the style while the application is running.
Because a VCL style is simply a particular kind of binary file, we can allow our users to load their preferred styles at runtime. We could even provide new styles by publishing them on a website or sending them by email to our customers.
In this recipe, we'll change the style while the application is running using a style already linked at design time, or let the user choose between a set of styles deployed inside a folder.
Style manipulation at runtime is done using the class methods of the TStyleManager class. Follow these steps to change the style of your VCL application at runtime:
Create a brand new VCL application and add the
Vcl.Themes
and
Vcl.Styles
units to the main form's
implementation uses
section. These units are required to use VCL styles at runtime.
Drop on the form a
TListBox
, two
TButton
, and a
TOpenDialog
. Leave the default component names.
Go to
Project
|
Appearance
and select eight styles of your choice from the list. Leave the
Default style
as
Windows
.
The
TStyleManager.StyleNames
property contains the names of all the available styles. In the
FormCreate
event handler, we have to load the already linked styles present in the executable to the listbox to let the user choose one of them. So, create a new procedure called
StylesListRefresh
with the following code and call it from the
FormCreate
event handler:
procedure
TMainForm.StylesListRefresh;
var
stylename: string;
begin
ListBox1.Clear; // retrieve all the styles linked in the executable
for
stylename
in
TStyleManager.StyleNames
do
begin
ListBox1.Items.Add(stylename);
end; end;
In the
Button2Click
event handler, we set the current style according to the one selected from the
ListBox1
using the code that follows:
TStyleManager.SetStyle(ListBox1.Items[ListBox1.ItemIndex]);
The
Button1Click
event handler should allow the user to select a style from the disk. So, we have to create a folder named
styles
at the level of our executable and copy a
.vsf
file from the default
styles
directory, which in RAD Studio 10.2 Tokyo is
C:\Program Files (x86)\Embarcadero\Studio\19.0\Redist\styles\vcl
.
After copying, write the following code under the
Button1Click
event handler. This code allows the user to choose a
style
file directly from the disk. Then, you can select one of the loaded styles from the listbox and click on
Button1
to apply it to
application
:
if
OpenDialog1.Execute
then
begin
if
TStyleManager.IsValidStyle(OpenDialog1.FileName)
then
begin
// load the style file TStyleManager.LoadFromFile(OpenDialog1.FileName); // refresh the list with the currently available styles StylesListRefresh; ShowMessage('New VCL Style has been loaded');
end
else
ShowMessage('The file is not a valid VCL Style!');
end
;
end
;
Just to give you an idea of how the different controls appear with the selected style, drag and drop some controls onto the right-hand side of the form.
Hit
F9
(or go to
Run
|
Run
), and play with your application, using and loading styles from the disk.
The following screenshot shows my application with some styles loaded, some at design time and some from the disk
:
The TStyleManager class has all the methods we need to do the following:
Inspect the loaded styles with
TStyleManager.StyleNames
Apply an already loaded style to the running application using the following code:
TStyleManager.SetStyle('StyleName')
Check whether a file has a valid style using the following code:
TStyleManager.IsValidStyle('StylePathFileName')
Load a style file from disk using the following code:
TStyleManager.LoadFromFile('StylePathFileName')
After loading new styles from disk, the new styles are completely identical to the styles linked in the executable during the compile and link phases and can be used in the same way.
Other things to consider are third-party controls. If your application uses third-party controls, take care with their style support (some third-party controls are not style-aware). If your external components do not support styles, you will end up with some styled controls (the originals included in Delphi) and some that are not styled (your external third-party controls).
Go to Tools | Bitmap Style Designer. Using a custom VCL Style, we can also:
Change application colors, such as
ButtonNormal
,
ButtonPressed
,
ButtonFocused
,
ButtonHot
, and others.
Override system colors, such as
clCaptionText
,
clBtnFace
,
clActiveCaption
, and so on.
Font color and font name for particular controls should be familiar to
ButtonTextNormal
,
ButtonTextPressed
,
ButtonTextFocused
,
ButtonTextHot
, and many others:
The adage a picture is worth a thousand words refers to the notion that a complex idea can be conveyed with just a single still image. Sometimes, even a simple concept is easier to understand and nicer to see if it is represented by images. In this recipe, we'll see how to customize TDBGrid to visualize a graphical representation of data.
Many VCL controls are able to delegate their drawing, or part of it, to user code. It means that we can use simple event handlers to draw standard components in different ways. It is not always simple, but TDBGrid is customizable in a really easy way. Let's say that we have a class of musicians that have to pass a set of exams. We want to show the percent of exams already passed with a progress bar and if the percent age is higher than 50, there should also be a check mark in another column. Moreover, after listening to the pieces played at the exams, each musician received votes from an external examination committee. The last column needs to show the mean of votes from this committee as a rating from zero to five.
By setting the TDBGrid property Default Drawing to False, we told the grid that we wanted to manually draw all the data into every cell. OnDrawColumnCell allows us to actually draw using standard Delphi code. For each cell we are about to draw, the event handler was called with a list of useful parameters to know which cell we're about to draw and what data we have to read, considering the column we are currently drawing. In this case, we want to draw only the calculated columns and the Rating field in a custom way. This is not a rule, but this can be done to manipulate all cells. We can draw any cell in the way we like. For the cells where we don't want to do custom drawing, a simple call method, DefaultDrawColumnCell, passes the same parameters we got from the event and the VCL code will draw the current cell as usual.
Among the event parameters, there is a Rect object (of type TRect) that represents the specific area we're about to draw. There is a column object (of type TColumn), which is a reference to the current column of the grid, and a State (of type TGridDrawState), which is a set of the grid cell states (for example, Selected, Focused, HotTrack, and many more). If our drawing code ignores the State parameter, all the cells will be drawn in the same way, and users cannot see which cell or row is selected.
The event handler uses a Pascal Sets Intersect to know whether the current cell should be drawn as a Selected or Focused cell. Refer to the following code for better clarity:
if
[gdSelected, gdFocused] * State <> []
then
Grid.Canvas.Brush.Color := clHighlight;
Owner drawing is a really large topic and can be simple or tremendously complex, involving much Canvas-related code. However, often, the kind of drawing you need will be relatively similar. So, if you need checks, arrows, color gradients, and so on, check the procedures into the Vcl.GraphUtil unit. Otherwise, if you need images, you could use TImageList to hold all the images needed by your grid, as we did in this recipe for the Rating field.
The good news is that the drawing code can be reused by different kinds of controls, so try to organize your code in a way that allows code reutilization by avoiding direct dependencies to the form where the control is.
The code in the drawing events should not contain business logic or presentation logic. If you need presentation logic, put it in a separate, testable function or class.
Many things are organized in a list. Lists are useful when you have to show items or when your user has to choose from a set of possible options. Usually, standard lists are flat, but sometimes you need to transmit more information in addition to a list of items. Let's think about when you go to choose a font in an advanced text editor such as Microsoft Word or Apache OpenOffice. Having the name of the font drawn in the font style itself helps users make a faster and more reasoned choice. In this recipe, we'll see how to make listboxes more useful. The code is perfectly valid for TComboBox as well.
As we saw in the Customizing TDBGrid recipe, many VCL controls are able to delegate their drawing, or part of it, to user code. This means that we can use simple event handlers to draw standard components in different ways. Let's say that we have a list of products in our store and we have to set discounts for these products. As there are many products, we want to set up the processing so that our users can make a fast selection in terms of the available discount percentages using a color code.
The TListBox.OnDrawItem event handler allows us to customize the drawing of the listbox. In this recipe, we've used TImageList as the image repository for the listbox. Using the Index parameter, we've read the correspondent image in TImageList and drawn on the listbox Canvas. After this, all the other code is related to the alignment of image and text inside the listbox row.
Remember that this event handler will be called for each item in the list, so the code must be fast and should not do too much slow canvas writing. Otherwise, your GUI will be unresponsive. If you want to create complex graphics on the fly in the event, I strongly suggest that you prepare your images the first time you draw the item and then put them in a sort of cache memory (TObjectList<TBitmap> is enough).
While you are in OnDrawItem, you can do whatever you want with the TListBoxCanvas. Moreover, the State parameter (of type TOwnerDrawState) tells you which states the listbox item is in (for example, Selected, Focused, HotTrack, and so on). So, you can use a different kind of drawing, depending on the item state. Check out the Customizing TDBGrid recipe to find out about TDBGrid owner-drawing for an example of the State parameter.
If you want to make your code aware of the selected VCL Style, changing the color used according to the style, you can use StyleServices.GetStyleColor(), StyleServices.GetStyleFontColor(), and StyleServices.GetSystemColor() in the Vcl.Themes unit.
The icons used in this recipe are from the ICOJAM website (http://www.icojam.com). The specific set used is available at http://www.icojam.com/blog/?p=259.
Owner-draw controls are powerful. They allow you to completely adapt your GUI to the needs of your users and potentially enable your application to display data in a more familiar way. In the end, owner-draw controls improve the user's experience with the application. However, owner-draw controls do not always fit in well with the VCL custom styles. Why? Because if you try to draw something by yourself, you could be tempted to use a fixed color, such clRed or clYellow, or you could be tempted to use the operating system color, such as clBtnFace or clWindow. In doing so, your owner-draw controls will not be style aware and will be drawn in the same way regardless of the current VCL style. In this recipe, you'll learn how to make custom graphics that remain relevant to the selected VCL style.
Let's say you are in charge of developing a control panel for a hotel's lighting system. You have a list of lamps to power on and you, using some hardware, have to power on some lamps by clicking on a button. Customers tell you that buttons should show some additional information about the lamp, for example:
Served zone (corridor, hall, room number, and so on)
State (on/off, using some fancy graphics)
The time the lamp was powered on
The time when electrical problems were detected, and a red icon to indicate that the lamp is off even when a current supplies the line, so the circuit is interrupted somewhere
Other custom information not currently known, such as small graphs showing lamp state history during the last 24 hours
The question is how to implement this kind of UI. One of the possible ways is to use TDrawGrid and draw all the required details in each cell, using the cell as a button. Using TDrawGrid, you get a grid of buttons for free. You have also the greatest flexibility in terms of the information displayed because you are using the TCanvas method to custom draw each cell. This is quite a popular solution for this kind of non-standard UI.
However, when you deploy this application, the customers ask about the possibility of changing the style of the application to fit the needs of the current user. So you think about VCL styles, and you are right. However, the graphics drawn into the cells don't follow the currently selected VCL style, and your beautiful application becomes a bad mix of colors. In other words, when users change the selected VCL style, all the controls reflect the new style, but the owner-drawn grid, which is unaware to the selected style, doesn't look as nice as the rest of the UI. How do you solve this problem? How do you draw custom graphics adhering to the selected VCL style? In this recipe, you'll learn how to do it using the lamp control grid example.
