Character Map

Peter Kiers
Peter Kiers used Ask the Experts™
on
Dear experts,

I have made a Character Map for my application. But there are a few
things that are not correct.

1. When the user clicks on the menu-item Special Character the form
    CharacterMap will be showed. But at the startup no font is selected
    in the combobox and the grid is not filled (picture1).

2. When I open the combobox to choose a font the fontlist is almost
    unreadable (picture2)

3. And the character in the cell of the grid should be aligned with the cell (see picture3).

Who knows the answer and is willing to help me?

I have put the code in the code-section.

Greetings, Peter Kiers
Calling from the main form:

procedure TMainForm.SpecialCharacter1Click(Sender: TObject);
begin
  CharacterMap.show;
end;

unit CharMap;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, Buttons;

type
  TCharacterMap = class(TForm)
    ComboBox1: TComboBox;
    StringGrid1: TStringGrid;
    Label1: TLabel;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    procedure ComboBox1MeasureItem(Control: TWinControl; Index: Integer;
      var Height: Integer);
    procedure ComboBox1DrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    procedure ComboBox1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  CharacterMap: TCharacterMap;

implementation

{$R *.dfm}

procedure TCharacterMap.ComboBox1Change(Sender: TObject);
var 
 i, z: Integer;
begin 
 StringGrid1.Font.Name := ComboBox1.Text; 
 for z := 0 to 6 do
  for i := 0 to 31 do 
   StringGrid1.Cells[i, z] := Chr((i + 1) * (z + 1) + 31); 
end;
(*---------------------------------------------------*)
procedure TCharacterMap.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin 
  with Control as TComboBox do 
  begin
    Canvas.Font.Name := Items[Index]; 
    Canvas.FillRect(Rect); 
    Canvas.TextOut(Rect.Left, Rect.Top, Items[Index]);
  end; 
end; 
(*---------------------------------------------------*)
procedure TCharacterMap.ComboBox1MeasureItem(Control: TWinControl;
  Index: Integer; var Height: Integer);
var 
  h: integer;
begin
  with Control as TComboBox do
  begin
    Canvas.Font.Name := Items[Index];
    h := Canvas.TextHeight(Items[Index]);
  end;
  Height := h;
end;
(*---------------------------------------------------*)
procedure TCharacterMap.FormCreate(Sender: TObject);
begin
 ComboBox1.Items := Screen.Fonts;
end;
(*---------------------------------------------------*)
end.

object CharacterMap: TCharacterMap
  Left = 0
  Top = 0
  BorderStyle = bsDialog
  Caption = 'Character Map'
  ClientHeight = 298
  ClientWidth = 713
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poMainFormCenter
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 20
    Top = 23
    Width = 26
    Height = 13
    Caption = 'Font:'
  end
  object ComboBox1: TComboBox
    Left = 52
    Top = 20
    Width = 145
    Height = 22
    Style = csOwnerDrawFixed
    ItemHeight = 16
    TabOrder = 0
    OnChange = ComboBox1Change
    OnDrawItem = ComboBox1DrawItem
    OnMeasureItem = ComboBox1MeasureItem
  end
  object StringGrid1: TStringGrid
    Left = 28
    Top = 48
    Width = 677
    Height = 181
    ColCount = 32
    DefaultColWidth = 20
    FixedCols = 0
    RowCount = 7
    FixedRows = 0
    TabOrder = 1
  end
  object BitBtn1: TBitBtn
    Left = 504
    Top = 256
    Width = 75
    Height = 25
    Caption = 'OK'
    ModalResult = 1
    TabOrder = 2
  end
  object BitBtn2: TBitBtn
    Left = 600
    Top = 256
    Width = 75
    Height = 25
    Caption = 'Cancel'
    ModalResult = 1
    TabOrder = 3
  end
end

Open in new window

Example1.bmp
Example2.bmp
Example3.bmp
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
1) If you want a font to already be shown try adding "ComboBox1.ItemIndex = 0" after line 78. If this doesn't trigger the OnChange event of ComboBox1 you can manually call it with a "ComboBox1Change(ComboBox1)" call after the ItemIndex line.

2) Well the text is unreadable in the combobox because you show the font name in the font itself. Try removing this by commenting out lines 46 and 70.(My guess at least).

3) The easiest way to fix this is to increase the font size of the entered characters to a higher amount to make it look centered. Otherwise the only other option you have is to set the DefaultDrawing property of StringGrid1 to false and handle the StringGrids DrawCell event yourself.
Commented:
Hi again,
 
1) ThievenSix answer solves the problem
2) Remove only line 70 not line 46
3) use the following code to center stringrid cells:

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
 WriteText(StringGrid1.Canvas, Rect, StringGrid1.Cells[acol, arow]);
end;

procedure TForm1. WriteText(ACanvas: TCanvas; const ARect: TRect; const Text: string);
var
 S: array[0..255] of Char;
begin
 with ACanvas, ARect do
  ExtTextOut(Handle, Left + (Right - Left - TextWidth(Text)) div 2, Top + (Bottom - Top - TextHeight(Text)) div 2,
  ETO_OPAQUE or ETO_CLIPPED, @ARect, StrPCopy(S, Text), Length(Text), nil);
end;
Peter KiersOperator

Author

Commented:
Hi,

Sorry, for a late response, I lost my internet-connection.

1) I think the best way is use them both:

procedure TCharacterMap.FormCreate(Sender: TObject);
begin
 ComboBox1.Items := Screen.Fonts;
 ComboBox1.ItemIndex := 0;  //choose the first font in the index
ComboBox1Change(ComboBox1); //get the characters in the grid by the font that is chosen
end;

2) twinsoft is right remove only 70 not 46.
3) the code is not really helping.

by the way, in the oncreate I want to call for the True Type font only.
How can I do that?

Peter Kiers
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

Peter KiersOperator

Author

Commented:
Ignore 3 because it does work i forgot the StringGrid1DrawCell-procedure.

P.
Peter KiersOperator

Author

Commented:
So this question remains before i give the points:

In the combobox I want true type font only, how can i do that?

Peter Kiers

Commented:
Hi, i think i should have been awarded the accepted solution, because i gave u a ready solution to your problem when ThievingSix gave you one wrong answer (2) and he only suggested a solution without providing the code for it (3).
Anyway, if you want the solution to your last question about true type fonts, please open a new question, i have just prepared the code for it...

Commented:
Hi,
  just saw that you already posted a question for the true type fonts, so ignore it..

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial