Newsgroups : Borland : borland.public.delphi.nativeapi.win32 : 2007 May : Using canvas.gettextwidth in onCreate event

www.cryer.info
Managed Newsgroup Archive

Using canvas.gettextwidth in onCreate event

Subject:Using canvas.gettextwidth in onCreate event
Posted by:"Joe H" (joedot..@att.net)
Date:1 May 2007 07:46:53

I hope this isn't one of those questions where everyone knows the
answer but me but I've looked extensively and can't find the answer
anywhere.

The problem is, I know, for example, the maximum amount of data that
needs to be shown in a grid column. I'm using virtual data so allowing
the grid to read all the rows to compute the maximum size takes way too
long. In setting up the grid, I use
grid.canvas.gettextwidth('99/99/9999') for example as the bare width of
a date column. I then have to add the gridline widths and whatever
blank spacing is required.

Problem is, I need to do this before the grid is displayed and so I'm
trying to do it in the oncreate event. But the resulting width I get is
always too small. I'm assuming that the grid's font is set to a larger
(or smaller) value than the form. If I leave out the font size setting
the data formats properly. If I put a button on the form to re-compute
the column widths after the form has shown once, the results are
exactly correct again.

So what I need is some way to maybe createcompatibleBitmap? or a way to
force the grid canvas (in this example) to reset itself to the correct
font or something, where I can set the desired font size and attributes
and then use that canvas to compute the size of my maximum data. I run
into the same problem in printing unless I start BeginDoc, all of the
getTextWidth or GetTextHeight functions return incorrect values.

To demonstrate the problem, put a StringGrid on a blank form, add a
button to recalculate sizes. then write a procedure to set the grid's
parameters, like:

procedure tForm1.SetGrid;
var
  i:   integer;
begin
  grid.font.size := self.font.size+4;
  grid.colcount := 5;
  grid.rowcount := 5;
  grid.FixedRows := 1;
  Grid.FixedCols := 1;
  grid.colwidths[0] := 4+grid.canvas.textwidth('Line #');
  grid.ColWidths[1] := 4+grid.canvas.textwidth('99/99/9999');
  grid.colwidths[2] := 4+grid.canvas.textwidth('9999-9999-9999-9999');
  grid.colwidths[3] := 4+grid.canvas.textwidth('99/99');
  grid.colwidths[4] := 4+grid.canvas.textwidth('99,999.99');
  grid.cells[0,0] := 'Line #';
  grid.Cells[1,0] := '  DATE  ';
  grid.cells[2,0] := 'CARD NUMBER';
  grid.cells[3,0] := 'Exp';
  grid.Cells[4,0] := 'Amount';
  for i := 1 to 4 do
  begin
    grid.cells[0,i] := intToStr(i);
    grid.cells[1,i] := DateToStr(Now-4+i); // show last 4 days
    grid.cells[2,i] := '1234-5678-9012-3456';
    grid.cells[3,i] := '07/11';
    grid.cells[4,i] := '12,345.67';
  end;
end;

//now in the forms's oncreate event, and in the button's onclick event,
//call setgrid.

procedure TForm1.FormCreate(sender: tObject);
begin
  setGrid;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  setGrid;
end;


When you run this, initially the fields will not fit in their fields
but when you click the button they will fit perfectly.

--

Replies:

www.cryer.info
Managed Newsgroup Archive