Practical Learning Logo

Custom List of Fonts


Introduction

Many applications provide a control that displays a list of fonts so that the control itself gives a preview of the font. This allows the user to make a better selection of the desired font. To create such a list of font, you can draw each item of the list as if it were a small graphic. As most of those controls are list-based, the most commonly used is the combo box but you can also use a list box, a menu item, or a tree view.

Creating a Custom List of Fonts

To create a custom list of fonts, you must first decide what control you will be using. For this  example we use a list box named ListBox1 and a combo box named ComboBox1. The control must get prepared to have each item individually drawn. For a list box or a combo box, the control should have an "owner draw" style. For this example, we make the list box lbOwnerDrawFixed and we make the combo box csOwnerDrawFixed. By default, the fonts in the computer system receive a size of 10, which is fine but could make come fonts difficult to preview on a control. Therefore, you should change the height of each item of the list. For this example, you can set the ItemHeight of each control to 20:

 

Before drawing the list, the control should have a list of items (fonts) that will themselves be used as string. We know that the VCL makes it extremely simply to fill out a control with the list of fonts in the computer. For our example, we can use the OnCreate event of the form to initialize the controls as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    // Fill out the control with the fonts of the computer
    for(int i = 0; i < Screen->Fonts->Count; i++)
    {
        ListBox1->Items->Add(Screen->Fonts->Strings[i]);
        ComboBox1->Items->Add(Screen->Fonts->Strings[i]);
    }

    int F = ComboBox1->Items->IndexOf("Times New Roman");
    if( F ) // If the font exists, select it
        ComboBox1->ItemIndex = F;
}
//---------------------------------------------------------------------------

The only thing left to do is to draw each item of the list by changing its font. This can be taken care of in the OnDrawItem of the control. Here is the implement of each of these events:
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1DrawItem(TWinControl *Control, int Index,
      TRect &Rect, TOwnerDrawState State)
{
    if( State.Contains(odSelected) )
        ListBox1->Canvas->Brush->Color = clHighlight;
    else
        ListBox1->Canvas->Brush->Color = clWhite;


    ListBox1->Canvas->FillRect(Rect);

    ListBox1->Canvas->Pen->Color = clWhite;
    ListBox1->Canvas->Font->Name = ListBox1->Items->Strings[Index];
    ListBox1->Canvas->Font->Size = 12;
    ListBox1->Canvas->TextOut(Rect.Left, Rect.Top,
				ListBox1->Items->Strings[Index]);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
      TRect &Rect, TOwnerDrawState State)
{
    if( State.Contains(odSelected) )
        ComboBox1->Canvas->Brush->Color = clHighlight;
    else
        ComboBox1->Canvas->Brush->Color = clWhite;

    ComboBox1->Canvas->FillRect(Rect);

    ComboBox1->Canvas->Font->Name = ComboBox1->Items->Strings[Index];
    ComboBox1->Canvas->Font->Size = 12;
    ComboBox1->Canvas->TextOut(Rect.Left, Rect.Top-2,
			 ComboBox1->Items->Strings[Index]);
}
//---------------------------------------------------------------------------

You can use this same technique in other controls.

 


Copyright 2004-2007 FunctionX, Inc.