Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Contar letras en un TMemo (https://www.clubdelphi.com/foros/showthread.php?t=39871)

roman 01-02-2007 02:53:39

A ver, si lo que se quiere es descontar los saltos de línea y sabemos que hay dos caracteres por cada salto, ¿no es más facil tomar la longitud del texto y restarle 2 veces el número de líneas?

Código Delphi [-]
procedure TForm1.Memo1Change(Sender: TObject);
var
  L, I: Integer;

begin
  L := Memo1.Perform(EM_GETLINECOUNT, 0, 0);
  I := Length(Memo1.Lines.Text) - 2*(L - 1);

  Edit1.Text := Format('%d caracteres', [i]);
end;

// Saludos

seoane 01-02-2007 03:39:31

¿y por que no?

Código Delphi [-]
var
  i,j: integer;
begin
  j:= 0;
  for i:= 0 to Memo1.Lines.Count do
    inc(j,Length(Memo1.Lines[i]));
  Caption:= IntToStr(j);
end;

En los códigos anteriores estamos usando la propiedad Text, que no existe como tal, si no que se crea juntando todas las lineas en un solo string, con la consecuente perdida de tiempo en ese bucle. Así que es mejor acceder directamente a cada linea y sumar sus longitudes, así también eliminamos los saltos de linea y evitamos andar moviendo los caracteres de un string a otro antes de contarlos.

:D cuantas formas de "despellejar a un gato" ...

roman 01-02-2007 03:54:53

La propiedad Text se obtiene mandando el mensaje WM_GETTEXT. La verdad es que hubiera jurado que era como tú decías pero revisando el código de la VCL se ve eso.

// Saludos

seoane 01-02-2007 04:08:01

Cita:

Empezado por roman
La propiedad Text se obtiene mandando el mensaje WM_GETTEXT. La verdad es que hubiera jurado que era como tú decías pero revisando el código de la VCL se ve eso.

// Saludos

Al menos en mi version de delphi no:
Código Delphi [-]
function TStrings.GetTextStr: string;
var
  I, L, Size, Count: Integer;
  P: PChar;
  S, LB: string;
begin
  Count := GetCount;
  Size := 0;
  LB := LineBreak;
  for I := 0 to Count - 1 do Inc(Size, Length(Get(I)) + Length(LB));
  SetString(Result, nil, Size);
  P := Pointer(Result);
  for I := 0 to Count - 1 do
  begin
    S := Get(I);
    L := Length(S);
    if L <> 0 then
    begin
      System.Move(Pointer(S)^, P^, L);
      Inc(P, L);
    end;
    L := Length(LB);
    if L <> 0 then
    begin
      System.Move(Pointer(LB)^, P^, L);
      Inc(P, L);
    end;
  end;
end;

Ahora bien, puede que tu estés hablando de Memo1.Text y no de Memo1.Lines.Text. En el primer caso si que se obtiene con WM_GETTEXT, no así en el segundo caso, como se puede ver en el código anterior.

egostar 01-02-2007 04:10:40

Gracias Roman

Tu código también esta de 10.

YA lo probe y esta perfecto, bien dices seoane, hay muchas fformas de "despellejar a un gato":D

Cuantas formas diferente de hacer esto.

Saludos

roman 01-02-2007 04:18:49

En Delphi 7 es igual, sólo que tú estás hablando de TStrings.Text, pero la propiedad Lines del TMemo es de tipo TMemoStrings que redefine GetTextStr

Código Delphi [-]
function TMemoStrings.GetTextStr: string;
begin
  Result := Memo.Text;
end;

y es Memo.Text la que se obtiene usando WM_GETTEXT.

// Saludos

seoane 01-02-2007 04:23:51

Cita:

Empezado por roman
pero la propiedad Lines del TMemo es de tipo TMemoStrings

:confused:

Código Delphi [-]
  property Lines: TStrings read FLines write SetLines;

roman 01-02-2007 04:29:33

Claro, así está declarada para que sea compatible con TStrings, pero se construye usando TMemoStrings:

Código Delphi [-]
constructor TCustomMemo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Width := 185;
  Height := 89;
  AutoSize := False;
  FWordWrap := True;
  FWantReturns := True;
  FLines := TMemoStrings.Create;
  TMemoStrings(FLines).Memo := Self;
  ParentBackground := False;
end;

// Saludos

seoane 01-02-2007 04:33:51

Perfecto, esto me aclara algunas cosas. Gracias roman :)

roman 01-02-2007 04:39:43

De hecho, por eso hubiera jurado que era como tú decías. Siendo TStrings una clase independiente de cualquier control, pues no hay forma de obtener el texto total como no sea concatenando de una u otra forma cada línea. Pero esa es la maravilla de TStrings, una clase base sumamente versátil pero perfectamente adecuada para muchos descendientes. Creo que muchos controles hacen los mismo: combos, listbox, etc.

Ahora, si- como sería más lógico -se decide descartar también los espacios en el conteo como comenta Caral, no cabe duda que tú código y el de ArdiIIa en ensamblador son lo óptimo.

// Saludos

egostar 01-02-2007 05:12:06

Cita:

Empezado por roman
Ahora, si- como sería más lógico -se decide descartar también los espacios en el conteo como comenta Caral, no cabe duda que tú código y el de ArdiIIa en ensamblador son lo óptimo.

Pues muchas gracias por los aportes, incluso esto que dices Roman me parece que debo platicarlo con mi cliente porque si, efectivamente, suena lo mas lógico, ademas de hacer lo que nos piden una parte fundamental de ser programador es la de asesorar a los clientes y entregar un producto que se agradezca;) .

Saludos.


La franja horaria es GMT +2. Ahora son las 15:01:25.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi