Solved

Compute the length of a Tedit text component

Posted on 2009-04-14
16
1,399 Views
Last Modified: 2013-11-23
I have a TEdit component on a form
Depending on the length of the string that is in its Text properties, I want to adapt the Tedit width
How can I determine that length ?
Thanks
0
Comment
Question by:LeTay
  • 7
  • 6
  • 3
16 Comments
 
LVL 3

Expert Comment

by:btframework
ID: 24135767
Use functions GetTextExtentPoint32, GetDC
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 24135769
there is a function in the canvas that does this:

Edit.Canvas.TextWidth(Edit.Text);

you may experience race conditions
The width of the Edit doesn't normally change, and when it does it will force a redraw
determining the width of the text is done in the drawing of the component too
0
 
LVL 3

Expert Comment

by:btframework
ID: 24135789
Hm. Delphi 6, TEdit has no Canvas property. Or I miss something?
0
Migrating Your Company's PCs

To keep pace with competitors, businesses must keep employees productive, and that means providing them with the latest technology. This document provides the tips and tricks you need to help you migrate an outdated PC fleet to new desktops, laptops, and tablets.

 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 24135809
it is a windowed control and window controls have a Device Context
you just need to wrap it with a little Delphi code to use TCanvas

function EditTextWidth(Edit: TEdit): Integer;
var
  C: TCanvas;
  h: THandle;
begin
  c := TCanvas.Create;
  try
    h := Edit.Handle;
    c.Handle := Edit.GetDeviceContext(h);
    Result := c.TextWidth(Edit.Text);
  finally
    FreeAndNil(c);
  end;
end;
0
 
LVL 3

Expert Comment

by:btframework
ID: 24135832
Much shorter code you will have if use GetDC and GetTextExtentPoint32 :) (Which do exactly the same as your code).
0
 

Author Comment

by:LeTay
ID: 24135926
Well, in fact I made a little mistake in my question
I do not really want to adapt the component width
I want to be able to calculate it is too short and take necessary action on the text string
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 24135933
and what action would that be ?
reduce it ?
0
 

Author Comment

by:LeTay
ID: 24136002
Yes, reduce the string itself, as it is currently formatted a specific way
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 24136032
what about a function to give you the portion which is visible ?
function VisibleEditText(Edit: TEdit): string;
var
  C: TCanvas;
  h: THandle;
  x: integer;
begin
  Result := Edit.Text;
  c := TCanvas.Create;
  try
    h := Edit.Handle;
    c.Handle := Edit.GetDeviceContext(h);
    x := c.TextWidth(Result);
    while (x > Edit.Width) and (Result <> '') do
    begin
      Delete(Result, Length(Result), 1);
      x := c.TextWidth(Result);
    end;
  finally
    FreeAndNil(c);
  end;
end;

Open in new window

0
 

Author Comment

by:LeTay
ID: 24155488
In fact I made a little mistake in my description of the problem
The component used for showing the string is a TLabel, not a TEdit
Is the code from Geert still valid ?
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 24155599
Ah, that's only a slight difference,
did you not set the Label.AutoSize to true ?

this automatically adjusts the Label size to fit all text of the caption ...

0
 

Author Comment

by:LeTay
ID: 24155613
In fact, the size and lay-out of the form is such that I have a limited place for this label (there are more of a dozen of such labels)
Autosizing the label is not a solution as it will "hit" another visual component
I need to use fixed width for the label, but I can "adjust" the string if too long
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 24155864
are all your labels the same font and fontsize and style ?
0
 

Author Comment

by:LeTay
ID: 24156015
Yes
0
 
LVL 37

Accepted Solution

by:
Geert Gruwez earned 500 total points
ID: 24156310
actually with a label it's even easier, you've got direct access to the canvas :

it set 2 wide TLabels and some panels

it reduces the caption of the labels to a specified width (in this case width of panel1)

function LimitedText(aText: string; aLabel: TLabel; aMaxWidth: integer; Enforce: boolean = false): string;
var
  x: integer;
begin
  Result := aText;
  x := aLabel.Canvas.TextWidth(Result);
  while (x > aMaxWidth) and (Result <> '') do
  begin
    Delete(Result, Length(Result), 1);
    x := aLabel.Canvas.TextWidth(Result);
  end;
  if Enforce then
    aLabel.Caption := Result;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var I: Integer;
  C: TControl;
begin
  for I := 0 to Panel2.ControlCount-1 do
  begin
    C := Panel2.Controls[I];
    if C is TLabel then
      LimitedText(TLabel(C).Caption, TLabel(C), Panel1.Width, True);
  end;
end;

Open in new window

0
 

Author Closing Comment

by:LeTay
ID: 31569805
Thanks a lot !
0

Featured Post

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question