[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Compute the length of a Tedit text component

Posted on 2009-04-14
16
Medium Priority
?
1,497 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 38

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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 38

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 38

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 38

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 38

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 38

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 38

Accepted Solution

by:
Geert Gruwez earned 2000 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

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

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

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
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…
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
Suggested Courses

834 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