Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Delphi Cookbook
Delphi Cookbook

Delphi Cookbook: 50 hands-on recipes to master the power of Delphi for cross-platform and mobile development on Windows, Mac OS X, Android, and iOS

eBook
$9.99 $28.99
Paperback
$48.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Delphi Cookbook

Chapter 1. Delphi Basics

In this chapter, we will cover the following recipes:

  • Changing your application's look and feel with VCL styles and no code
  • Changing the style of your VCL application at runtime
  • Customizing TDBGrid
  • Using the owner's draw combos and listboxes
  • Creating a stack of embedded forms
  • Manipulating JSON
  • Manipulating and transforming XML documents
  • I/O in the twenty-first century – knowing streams
  • Putting your VCL application in the tray
  • Creating a Windows service
  • Associating a file extension with your application on Windows

Introduction

This chapter explains 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 a lot of others because although they may be obvious for some experienced users, they are still very useful. Even if there is no specifically database-related code, many of the recipes can also be used (or sometimes especially used) when you are dealing with data.

Changing your application's look and feel with VCL styles and no code

VCL styles are a major new entry in the latest versions of Delphi. They have been introduced in Delphi XE2 and are still one of the less-known features for the good old Delphi developers. However, as usual, some businessmen say looks matter, so the look and feel of your application could be one of the reasons to choose your product over one 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 your applications. So why not give it a try?

Getting ready

VCL styles can be used to revamp an old application or to create a new one with a nonstandard GUI. VCL styles are a completely different beast to FireMonkey styles. They are both styles but with completely different approaches and behavior.

To get started with VCL styles, we'll use a new application. Let's create a new VCL application and drag-and-drop some components onto the main form (for example, two TButton components, one TListBox component, one TComboBox component, and a couple of TCheckBox components).

The following screenshot is the resultant form that runs on a Windows 7 machine:

Getting ready

A form without style

How to do it...

Now we've to apply a set of nice styles. To do this, perform the following steps:

  1. Navigate to Project | Options. In the resultant dialog, go to Application | Appearance and select all the styles that we want to include in our application.
  2. Using 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 will be used at a time, but we can link the necessary resources to the executable and select the proper one at runtime.
  3. After selecting all the required styles from the list, we've to select one in the combobox at the bottom of the screen. This style will be the default style for our form and will be loaded as soon as the application starts. You can delay this choice and make it at runtime using code if you prefer.
  4. Click on OK and hit F9 (or navigate to Run | Run) and your application is styled! The resultant form is shown in the following screenshot:
    How to do it...

    The same form as the preceding one but with the Iceberg Classico style applied

How it works…

Selecting one or more styles by navigating to Project | Options | Application | Appearance can cause the Delphi linker to link the style resource to your executable. It is possible to link many styles to your executable, but you can use only one style at time. So, how does Delphi know which style you want to use when there are more than one styles? If we check the Project file (the file with the .dpr extension) by navigating to Project | View Source, you can see where and how this little magic happens.

The following lines are the interesting part:

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  TStyleManager.TrySetStyle('Iceberg Classico');
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end.

When we've selected the Iceberg Classico style as the default style, the Delphi IDE adds a line just before the creation of the main form, setting the default style for the application using the TStyleManager.TrySetStyle static method.

TStyleManager is a very important class when dealing with VCL styles. We'll see more about it in the next recipe when we'll learn how to change a style at runtime.

There's more...

Delphi and C++Builder XE6 come with 29 VCL styles available in C:\Program Files (x86)\Embarcadero\Studio\14.0\Redist\styles\vcl\ (with a standard installation).

Moreover, it is possible to create your own styles or modify the existing ones by using the Bitmap Style Designer available at Tools | Bitmap Style Designer menu. The Bitmap Style Designer also provides test applications to test VCL styles.

For more details on how to create or customize a VCL style, check the following link:

http://docwiki.embarcadero.com/RADStudio/XE6/en/Creating_a_Style_using_the_Bitmap_Style_Designer

Changing the style of your VCL application at runtime

VCL styles are a powerful way to change the appearance of your application, but using them only as design-time tools is way too limited. One of the main features of a VCL style is the ability to change the style while an application is running.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Getting ready

Because a VCL style is simply a particular kind of binary file, we can allow our users to load their preferred style at runtime, and we can even provide new styles—publishing them on a website or sending them by an e-mail to our customers.

In this recipe, we'll be able to change the style while an 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.

How to do it…

Styles manipulation at runtime is done using the class methods of the TStyleManager class:

  1. Create a brand new VCL application and add the Vcl.Themes and Vcl.Styles units to the main implementation form. These units are required to use VCL styles at runtime.
  2. Drop on the form a TListBox component, two TButton components, and two TOpenDialog components. Leave the default component names.
  3. Go to Project | Appearance and select eight styles of your choice from the list. Leave the Default style option to Windows.
  4. The TStyleManager.StyleNames property contains all names of 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;
    
  5. In the Button1Click event handler, we've to set the current style according to the one selected from ListBox1 using the following code:
      TStyleManager.SetStyle(ListBox1.Items[ListBox1.ItemIndex]);
  6. The Button2Click event handler should allow the user to select a style from disk. So, we have to create a folder named styles at level of our executable and copy a few .vsf files from the default style directory which is C:\Program Files (x86)\Embarcadero\Studio\14.0\Redist\styles\vcl\ in RAD Studio XE6.
  7. After copying the files, write the following code under the Button2Click event handler. This code allows the user to chose 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 the application. The code is as follows:
    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;
    
  8. Just to have an idea of how the different controls appear with the selected style, drag-and-drop some controls to the right-hand side of the form. The following screenshot shows an application with some styles loaded, some at design time and some from the disk. Hit F9 (or go to Run | Run) and play with your application using and loading styles from the disk.
    How to do it…

    The Style Chooser form with a Turquoise Gray style loaded

How it works…

The TStyleManager class has all the methods we need:

  • Inspect the loaded styles with TStyleManager.StyleNames
  • Apply an already loaded style to the running application using TStyleManager.SetStyle('StyleName')
  • Check if a file is a valid style with TStyleManager.IsValidStyle('StylePathFileName')
  • Load a style file from disk using TStyleManager.LoadFromFile('StylePathFileName')

After loading new styles from the disk, these new styles are completely similar to the styles linked to the executable during the compile and link phases and can be used in the same way.

There's more...

Other things to consider are third-party controls. If your application uses third-party controls, take care with their style support. If your external components do not support styles, you will end up with some controls styled (the original included in Delphi) and some not (your external third-party controls)!

By navigating to Tools | Bitmap Style Designer and using a custom VCL style, we can also perform the following actions:

  • Change the application's colors (for example, ButtonNormal, ButtonPressed, ButtonFocused, ButtonHot, and so on)
  • Override the system's colors (for example, clCaptionText, clBtnFace, clActiveCaption, and so on)
  • Change the font color and font name for particular controls (for example, ButtonTextNormal, ButtonTextPressed, ButtonTextFocused, ButtonTextHot, and so on)

The following screenshot shows the Bitmap Style Designer window while working on a custom style:

There's more...

The Bitmap Style Designer while it is working on a custom style

Customizing TDBGrid

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 the TDBGrid object to visualize graphical representation of data.

Getting ready

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. 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 percentage of musicians who have already passed exams with a progress bar, and if the percent is higher than 50 percent, there should also be a check in another column.

How to do it…

We'll use a special in-memory table from the FireDAC library. FireDAC is a new data access library from Embarcadero, which is included in RAD Studio since Version XE5. If some of the code seems unclear at the moment, consider the in-memory table as a normal TDataSet descendant. However, at the end of this section, there are some links to the FireDAC documentation, and I strongly suggest you to read them if you still don't know FireDAC. To customize TDBGrid, perform the following steps:

  1. Create a brand new VCL application and drop on the form the TFDMemTable, TDBGrid, TDataSource, and TDBNavigator component. Connect all these components in the usual way (TDBGrid->TDataSource->TFDMemTable). Set the TDBGrid font size to 24. This will create more space in the cell for our graphical representation.
  2. Using the TFDMemTable fields editor, add the following fields and then activate the dataset setting by setting its Active property to True:

    Field name

    Field datatype

    Field type

    FullName

    String (size 50)

    Data

    TotalExams

    Integer

    Data

    PassedExams

    Integer

    Data

    PercPassedExams

    Float

    Calculated

    MoreThan50Percent

    Boolean

    Calculated

  3. In a real application, we should load real data from some sort of database. But for now, we'll use some custom data generated in code. We have to load this data into the dataset with the following code:
    procedure TMainForm.FormCreate(Sender: TObject);
    begin
      FDMemTable1.InsertRecord(
             ['Ludwig van Beethoven',30,10]);
      FDMemTable1.InsertRecord(
             ['Johann Sebastian Bach',24,10]);
      FDMemTable1.InsertRecord(
             ['Wolfgang Amadeus Mozart',30,30]);
      FDMemTable1.InsertRecord(
             ['Giacomo Puccini',25,10]);
      FDMemTable1.InsertRecord(
             ['Antonio Vivaldi',20,20]);
      FDMemTable1.InsertRecord(
             ['Giuseppe Verdi',30,5]);
    end;
    
  4. Do you remember? We've two calculated fields that need to be filled in some way. Create the OnCalcFields event handler on the TFDMemTable component and fill it with the following code:
    procedure TMainForm.FDMemTable1CalcFields(
       DataSet: TDataSet);
    var
      p: Integer;
      t: Integer;
    begin
      p := FDMemTable1.FieldByName('PassedExams').AsInteger;
      t := FDMemTable1.FieldByName('TotalExams').AsInteger;
      if t = 0 then
      begin
        FDMemTable1.FieldByName('PercPassedExams').AsFloat := 0
      end
      else
      begin
        FDMemTable1.
             FieldByName('PercPassedExams').
             AsFloat := p / t * 100;
      end;
    
    FDMemTable1.FieldByName('MoreThan50Percent').AsBoolean := FDMemTable1.
       FieldByName('PercPassedExams').AsFloat > 50;
    end;
    
  5. Run the application by hitting F9 (or navigating to Run | Run) and you will get the following screenshot:
    How to do it…

    A normal form with some data

  6. This is useful, but a bit boring. Let's start our customization. Close the application and return to Delphi IDE.
  7. Go to the TDBGrid properties and set DefaultDrawing to false.

    Go to the TDBGrid event and create an event handler for OnDrawColumnCell. All the customization code goes in this event.

    Include the Vcl.GraphUtil unit and write the following code in the DBGrid1DrawColumnCell event:

    procedure TMainForm.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn;
      State: TGridDrawState);
    var
      R: TRect;
      Grid: TDBGrid;
      S: string;
      WPerc: Extended;
      SSize: TSize;
      SavedPenColor: Integer;
      SavedBrushColor: Integer;
      SavedPenStyle: TPenStyle;
      SavedBrushStyle: TBrushStyle;
    begin
      Grid := TDBGrid(Sender);
      if [gdSelected, gdFocused] * State <> [] then
        Grid.Canvas.Brush.Color := clHighlight;
    
      if Column.Field.FieldKind = fkCalculated then
      begin
        R := Rect;
        SavedPenColor := Grid.Canvas.Pen.Color;
        SavedBrushColor := Grid.Canvas.Brush.Color;
        SavedPenStyle := Grid.Canvas.Pen.Style;
        SavedBrushStyle := Grid.Canvas.Brush.Style;
      end;
    
      if Column.FieldName.Equals('PercPassedExams') then
      begin
        S := FormatFloat('##0', Column.Field.AsFloat) + ' %';
        Grid.Canvas.Brush.Style := bsSolid;
        Grid.Canvas.FillRect(R);
        WPerc := Column.Field.AsFloat / 100 * R.Width;
        Grid.Canvas.Font.Size := Grid.Font.Size - 1;
        Grid.Canvas.Font.Color := clWhite;
        Grid.Canvas.Brush.Color := clYellow;
        Grid.Canvas.RoundRect(R.Left, R.Top, 
             Trunc(R.Left + WPerc), R.Bottom, 2, 2);
        InflateRect(R, -1, -1);
        Grid.Canvas.Pen.Style := psClear;
        Grid.Canvas.Font.Color := clBlack;
        Grid.Canvas.Brush.Style := bsClear;
        SSize := Grid.Canvas.TextExtent(S);
        Grid.Canvas.TextOut(
             R.Left + ((R.Width div 2) - (SSize.cx div 2)),
             R.Top + ((R.Height div 2) - (SSize.cy div 2)), 
             S);
      end
      else if Column.FieldName.Equals('MoreThan50Percent') then
      begin
        Grid.Canvas.Brush.Style := bsSolid;
        Grid.Canvas.Pen.Style := psClear;
        Grid.Canvas.FillRect(R);
        if Column.Field.AsBoolean then
        begin
          InflateRect(R, -4, -4);
          Grid.Canvas.Pen.Color := clRed;
          Grid.Canvas.Pen.Style := psSolid;
          DrawCheck(Grid.Canvas, 
            TPoint.Create(R.Left, R.Top + R.Height div 2), R.Height div 3);
        end;
      end
      else
        Grid.DefaultDrawColumnCell(Rect, DataCol, 
             Column, State);
    
      if Column.Field.FieldKind = fkCalculated then
      begin
        Grid.Canvas.Pen.Color := SavedPenColor;
        Grid.Canvas.Brush.Color := SavedBrushColor;
        Grid.Canvas.Pen.Style := SavedPenStyle;
        Grid.Canvas.Brush.Style := SavedBrushStyle;
      end;
    end;
    
  8. That's all, folks! Hit F9 (or navigate to Run | Run) and we now have a nicer grid with more direct information about our data:
    How to do it…

    The same grid with a bit of customization

How it works…

By setting the DBGrid property DefaultDrawing to false, we told the grid that we want to manually draw all the data into every cell. The OnDrawColumnCell event allows us to actually draw using the standard Delphi code. For each cell we are about to draw, the event handler is 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 currently drawn. In this case, we want to draw only the calculated columns in a customized 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 DefaultDrawColumnCell call method passing 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 Rect (of the TRect type) that represents the specific area we're about to draw, there is Column (of the TColumn type) that is a reference to the current column of the grid, and there is State (of the TGridDrawState type) that is a set of the grid cell states (for example, Selected, Focused, HotTrack, and so on). 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 sets intersection to know whether the current cell should be drawn as a selected or focused cell:

if [gdSelected, gdFocused] * State <> [] then
  Grid.Canvas.Brush.Color := clHighlight;

Tip

Remember that if your dataset has 100 records and 20 fields, the OnDrawColumnCell method will potentially be called 2,000 times! So the event code must be fast, otherwise the application will become less responsive.

There's more...

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 in the Vcl.GraphUtil unit. Otherwise, if you need images, you could use a TImageList class to hold all the images needed by your grid.

The good news is that the drawing code can be reused by different kind of controls, so try to organize your code in a way that allows code reutilization 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 and testable function or class.

Using the owner's draw combos and listboxes

Many things are organized in a list. Lists are useful when you have to show items or when your user has to choose among 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 OpenOffice.org. Having the name of the font drawn in the font style itself helps users to make a faster and more reasoned choice. In this recipe, we'll see how to make listboxes more useful. The code is perfectly valid also for a TComboBox.

Getting ready

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 on these products. As there are many products, we want to make it simple so that our users can make a fast selection between the available discount percentages using a color code.

How to do it…

  1. Create a brand new VCL application and drop on the form a TListBox component. Set the following properties:

    Property

    Value

    Style

    lbOwnerDrawFixed

    Font.Size

    14

  2. In the listbox Items property, add seven levels of discount. For example, you can use the following: no discount, 10 percent discount, 20 percent discount, 30 percent discount, 40 percent discount, 50 percent discount, and 70 percent discount.
  3. Then, drop a TImageList component on the form and set the following properties:

    Property

    Value

    ColorDepth

    cd32Bit

    DrawingStyle

    dsTransparent

    Width

    32

    Height

    32

  4. The TImageList component is our image repository and will be used to draw an image by index. Load seven PNG images (of 32 x 32 size) into TImageList. You can find some nice PNG icons in the recipe's project folder (ICONS\PNG\32).
  5. Create an OnDrawItem event handler for the TListBox component and write the following code:
    procedure TCustomListControlsForm.ListBox1DrawItem(
       Control: TWinControl; Index: Integer; 
       Rect: TRect; State: TOwnerDrawState);
    var
      LBox: TListBox;
      R: TRect;
      S: string;
      TextTopPos, TextLeftPos, TextHeight: Integer;
    const
      IMAGE_TEXT_SPACE = 5;
    begin
      LBox := Control as TListBox;
      R := Rect;
      LBox.Canvas.FillRect(R);
      ImageList1.Draw(LBox.Canvas, R.Left, R.Top, Index);
      S := LBox.Items[Index];
      TextHeight := LBox.Canvas.TextHeight(S);
      TextLeftPos := R.Left + 
       ImageList1.Width + IMAGE_TEXT_SPACE;
      TextTopPos := R.Top + R.Height div 2 - TextHeight div 2;
      LBox.Canvas.TextOut(TextLeftPos, TextTopPos, S);
    end;
    
  6. Run the application by hitting F9 (or navigate to Run | Run) and you will see the following screenshot:
    How to do it…

    Our listbox with some custom icons read from TImageList

How it works…

The TListBox.OnDrawItem event handler allows us to customize the drawing of the listbox. In this recipe, we used a TImageList component as the image repository for the listbox. Using the Index parameter, we read the correspondent image in the image list and drawn on the Canvas listbox. 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, all your GUI will be unresponsive. If you want to create complex graphics on the fly in the event, I strongly suggest you to prepare your images the first time you draw the item and then put them in a sort of cache memory (TObjectList<TBitmap> is enough).

There's more...

While you are in the OnDrawITem function, you can do whatever you want with the TListBox Canvas. Moreover, the State parameter (of the TOwnerDrawState type) tells you in which states the listbox item is (for example, Selected, Focused, HotTrack, and so on), so you can use different kind of drawings depending on the item's state. You can check the Customizing TDBGrid recipe to know about the TDBGrid owner drawing for an example ofthe State parameter.

If you want to make your code aware of the selected VCL style, changing the color used according to it, you can use StyleServices.GetStyleColor(), StyleServices.GetStyleFontColor(), and StyleServices.GetSystemColor() into 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.

Creating a stack of embedded forms

Every modern browser has a tabbed interface. Also, many other kinds of multiple views software have this kind of interface. Why? Because it's very useful. While you are reading one page, you can rapidly check another page, and then still come back to the first one at the same point you left some seconds ago. You don't have to redo a search or redo a lot of clicks to just go back to that particular point. You simply have switched from one window to another and back to the first. I see too many business applications that are composed by a bounce of dialog windows. Every form is called with the TForm.ShowModal method. So, the user has to navigate into your application one form at time. This is simpler to handle for the programmer, but it's less user-friendly for your customers. However, providing a switchable interface to your customer is not that difficult. In this recipe, we'll see a complete example on how to do it.

Getting ready

This recipe is a bit more complex than the previous recipes, so I'll not explain all the code but only the fundamental parts. You can find the complete code in the book's code repository (Chapter1\RECIPE05).

Let's say we want to create a tabbed interface for our software that is used to manage product orders, sales, and invoices. All the forms must be usable at the same time without having to close the previous one. Before we begin, the following screenshot is what we want to create:

Getting ready

The main form containing seven embedded child forms

How to do it...

The project is composed by a bounce of forms. The main form has a TTabControl component that allows switching between the active forms. All embedded forms inherit from EmbeddableForm. The most important is the Show method shown as follows:

procedure TEmbeddableForm.Show(AParent: TPanel);
begin
  Parent := AParent;
  BorderStyle := bsNone;
  BorderIcons := [];
  Align := alClient;
  Show;
end;

Note

Note that all the forms apart from the main form have been removed from the Auto-Create Form list (Project | Options | Forms).

All the other forms descend from the EmbeddableForm method and are added to the TTabControl component on the main form with a line of code similar to the following:

procedure TMainForm.MenuOrdersClick(Sender: TObject);
begin
  AddForm(TForm1.Create(self));
end;

The MainForm AddForm method is in charge of adding an actual instance of a form into the tabs, keeping a reference of it. The following code shows you how this is done:

//Add a form to the stack
procedure TMainForm.AddForm(
  AEmbeddableForm: TEmbeddableForm);
begin
  AEmbeddableForm.Show(Panel1);
  //each tab show the caption of the containing form and   
  //hold the reference to it
  TabControl1.Tabs.AddObject(
         AEmbeddableForm.Caption, AEmbeddableForm);
  ResizeTabsWidth;
  ShowForm(AEmbeddableForm);
end;

Other methods are in charge of bringing an already created form to the front when a user clicks on the related tab and then to close a form when the related tab is removed (check the ShowForm and WMEmbeddedFormClose methods).

How it works...

There is a bit of code, but the concepts are simple:

  • When we need to create a new form, add it in the TabControl1.Tabs property. The caption of the form is the caption of the tab, and the object is the form itself. This is what the AddForm method does with the following line:
    TabControl1.Tabs.AddObject(
       AEmbeddableForm.Caption, AEmbeddableForm);
  • When a user clicks on a tab, we have to find the associated form cycling through the TabControl1.Tabs.Objects list and bring it to the front.
  • When a form asks for closing (sending a WM_EMBEDDED_CLOSE message), we have to set the ParentWantClose property and then call the Close method of the correspondent form.
  • If a user wants to close a form by closing the correspondent tab (in the recipe code, there is a TPopMenu component connected to the TabControl component, which is used to close a form with a right-click), we have to call the Close method on the correspondent form.
  • Every form frees itself in the OnClose event handler. This is done once for all in the TEmbeddableForm.CloseForm event handler using the caFree action.

There's more...

Embedding a form into another TWinControl is not difficult and allows you to create flexible GUIs without using TPageControl and frames. For the end user, this multitabbed GUI is probably more familiar because all the modern browsers use it, and probably your user already knows how to use a browser with different pages or screens opened. From the developer point of view, the multitabbed interface allows for much better programming patterns and practices. This technique can also be used for other scenarios where you have to embed one screen into another.

More flexible (and complex) solutions can be created involving the use of Observers, but in simple cases, this recipe's solution based on Windows Messaging is enough.

More information about the Observer design pattern can be found at http://sourcemaking.com/design_patterns/observer/delphi.

Another interesting solution (that does not rely on Windows Messaging and so is also cross platform) may be based on the System.Messaging.TMessageManager class. More info about TMessageManager can be found at http://docwiki.embarcadero.com/Libraries/XE6/en/System.Messaging.TMessageManager.

The code in this recipe can be used with every component that uses TStringList to show items (TListBox, TComboBox, and so on) and can be adapted easily for other scenarios.

In the recipe code, you'll also find a nice way to show status messages generated by the embedded forms and a centralized way to show application hints in the status bar.

Left arrow icon Right arrow icon

Description

Intended to refresh the basics of Delphi as well as advance your knowledge to the next level, it is assumed you will know RAD studio and the Object Pascal language. However, if you are not an experienced RAD studio programmer this accessible guide will still develop those initial crucial skills.

What you will learn

  • Create visually stunning applications using FireMonkey
  • Effectively use LiveBindings with the right OOP approach
  • Create serverside programs to serve RESTful web services and provide data to your mobile apps
  • Develop mobile apps using welldefined GUI design patterns for a great user experience
  • Build efficient mobile apps that read data from a remote server
  • Call the platformnative API on Android and iOS even for an unpublished API
  • Use extended RTTI to better manage the software customization for your customer
  • Leverage the most popular design patterns for a better design without wasting too much time debugging
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Sep 25, 2014
Length: 328 pages
Edition : 1st
Language : English
ISBN-13 : 9781783559589
Category :
Languages :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Publication date : Sep 25, 2014
Length: 328 pages
Edition : 1st
Language : English
ISBN-13 : 9781783559589
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 158.97
Delphi Cookbook
$54.99
Delphi Cookbook
$48.99
Expert Delphi
$54.99
Total $ 158.97 Stars icon
Banner background image

Table of Contents

8 Chapters
1. Delphi Basics Chevron down icon Chevron up icon
2. Become a Delphi Language Ninja Chevron down icon Chevron up icon
3. Going Cross Platform with FireMonkey Chevron down icon Chevron up icon
4. The Thousand Faces of Multithreading Chevron down icon Chevron up icon
5. Putting Delphi on the Server Chevron down icon Chevron up icon
6. Riding the Mobile Revolution with FireMonkey Chevron down icon Chevron up icon
7. Using Specific Platform Features Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.5
(19 Ratings)
5 star 57.9%
4 star 31.6%
3 star 10.5%
2 star 0%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Schrabi Feb 21, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Das Buch hat wertvolle Tips und Tricks parat - kommt schnell zur Sache und hat state-of-the-art Rezepte. EInfach empfehlenswert! AAA+
Amazon Verified review Amazon
Disappointed consumer Jul 14, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Great recipes for my toolbox. The techniques are excellent and anyone who reads this book will walk away with a lot of good knowledge. Why aren't they more books like this one out there? If you are a Delphi programmer making a leaving in this field it behooves you to own this book. Dear Mr. author, please sign me up for the next recipe book and also please tell all your guru friends to contribute or write one too.
Amazon Verified review Amazon
David Millington Oct 30, 2014
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Covers an amazingly wide variety of topics, with examples that show a lot more than just the nominal subject. It shows 'modern Delphi' - the 2014 environment and language and capabilities. There's something in here even for experienced Delphi programmers, but if you haven't used Delphi for a long time, read it to get a great overview of the state of the language. If you're new to Delphi and need to learn, this book will cover the entire environment, and you'll be up to speed with a good general knowledge of the development environment quickly.Some of the post-recipe discussion could have more detail.Buy it? Yes.(This is a short version of a full review posted here: http://parnassus.co/review-delphi-cookbook-daniele-teti/ Please note that I was given a free review copy of the book by the publisher, but was not paid and have no undisclosed affiliations.)
Amazon Verified review Amazon
John Kaster Nov 26, 2014
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Before proceeding with my review, you may want to read this other review by Simon J Stuart which provides a good overview of what you can find in the book. I also received a review copy from the publisher, and I’m glad I requested one!Overall impressionThe book uses a great pattern, where a topic is introduced, code is shown to demonstrate it, explanations and observations about the technique are discussed, and suggestions for additional usage or other resources are provided. This “explore more” section of the book may actually be its most valuable part, because Daniele provides specific links that point to good resources to use for each of the recipes covered.The code examples are useful and as concise as is reasonable.The order of the book is logical and does a good job of building on some of the previous recipes in later parts of the book:1.Delphi Basics2.Become a Delphi Language Ninja3.Going Cross-Platform with FireMonkey4.The Thousand Faces of Multithreading5.Putting Delphi on the Server6.Riding the Mobile Revolution with FireMonkey7.Using Specific (mobile) Platform FeaturesThis is a valuable book to keep handy for when you may need to implement any of the techniques it covers. In short, it is exactly what a “cookbook” should be, with quick and reliable recipes to help you create a good solution for a technical issue.Some specificsFor example, there’s a great, short exploration for taking advantage of generics. Hidden in one of the discussed “higher order” functions for generics (map, reduce/fold, filter) is something that deserves to be called out briefly in the book (although it is not).class function HigherOrder.Filter(InputArray: TArray; FilterFunction: TFunc): TArray;var I: Integer; List: TList;begin List := TList.Create; try for I := 0 to length(InputArray) - 1 do if FilterFunction(InputArray[I]) then List.Add(InputArray[I]); Result := List.ToArray; finally List.Free; end;end;This small sample shows one of the cleaner methods of populating a dynamic array result that can subsequently be lifetime managed by the runtime. The TList object is efficient for growing one item at a time. A dynamic array is not. Often, the result for the dynamic array is preallocated to some high bound (in the sample above, it would be the length of the input array), then resized before the return to shrink the array back down to the number of elements matching the filter. By using TList<T>, then freeing it, the array size is only manipulated once and the List.ToArray call makes the code clean and sustainable.Mobile development with FiremonkeyThe book has many detailed and useful examples for mobile development with FireMonkey. This is the section of the book where I learned the most, because I haven’t worked on mobile apps with Delphi. There are many useful tidbits covered in this section that are important for mobile development: using mobile databases, implementing server and client-side functionality, camera and phone manipulation, application lifecycle awareness, and more.Platform-specific featuresThe platform-specific features chapter goes beyond mobile FireMonkey recipes to making calls from Delphi to iOS and Android SDK calls, and is an excellent way to wrap up the book.Other recipes I’d like to seeSome things I think would be good to have in the book are:•In the UI section: ◦effective use of actions◦effective use of frames◦input value validations (form validation)•in the section on streaming, it would be handy to explore reliable determination of the encoding used by a file.•for threading, effective use of the new XE7 Parallels library•for Delphi on the server, ◦how to secure your web application (including using secure CDN resources for jQuery, etc)◦using dynamic arrays and records for JSON to avoid all the “free” calls for TObjectList<T> (this works very well with SuperObject, for example)A minor nitI don’t understand what Daniele means by “bounce” as in: “I see too many business applications that are composed by a bounce of dialog windows.”ConclusionDaniele did a great job on this book, and I hope he continues to update it with new recipes in the future.
Amazon Verified review Amazon
PJ-Jim Apr 14, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Very useful book for the Delphi programmer. I have studied it many times and am awaiting the next book from this same author.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela