Book Image

Delphi Cookbook - Second Edition

By : Daniele Teti
Book Image

Delphi Cookbook - Second Edition

By: Daniele Teti

Overview of this book

Delphi is a cross-platform Integrated Development Environment (IDE) that supports rapid application development for Microsoft Windows, Apple Mac OS X, Google Android, and Apple iOS. It helps you to concentrate on the real business and save yourself the pain of wandering amid GUI widget details, or having to tackle inter-platform incompatibilities. It also has a wide range of drag-and-drop controls, helping you code your business logic into your business model, and it compiles natively for desktop and mobile platforms. This book will teach you how to design and develop applications, deploy them on the cloud platform, and distribute them within an organization via Google Play and other similar platforms. You will begin with the basics of Delphi and get acquainted with JSON format strings, XSLT transformations, unicode encodings and various types of streams. We then move on to more advanced topics such as developing higher-order functions and using enumerators and RTTI. You will get an understanding of how Delphi RTL functions and how to use FireMonkey in a VCL application. We will then cover topics such as multithreading, using the parallel programming library and putting Delphi on a server. We will also take a look at the new feature of WebBroker Apache modules and then ride the mobile revolution with FireMonkey. By the end of the book, you will be able to develop and deploy cross-platform applications using Delphi .
Table of Contents (15 chapters)
Delphi Cookbook Second Edition
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

Using owner 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 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.

Getting ready

As we saw in the recipe, Customizing TDBGrid, 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. 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 the processing in a way 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 a TListBox on the form. 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 no discount, 10 percent discount, 20 percent discount, 30 percent discount, 40 percent discount, 50 percent discount, 60 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. TImageList is our image repository and will be used to draw an image by index. Load 7 PNG images (size 32 x 32) into TImageList. You can find some nice PNG icons in the respective recipe project folder (ICONS\PNG\32).

  5. Create an OnDrawItem event handler for TListBox 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 by going to Run | Run) and you will see the following screenshot:

    Figure 4.1: 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'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, all 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).

There's more…

While you are in OnDrawItem, you can do whatever you want with the TListBox Canvas. Moreover, the State parameter (of type TOwnerDrawState) tells you in which states the listbox item is (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 the TDBGrid owner drawing for an example about the 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() 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.