Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Colocar Diferentes Tipo De Letra Ydiferentes Tamaños a Itens De Un Combobox (https://www.clubdelphi.com/foros/showthread.php?t=61833)

gulder 24-11-2008 15:30:47

Colocar Diferentes Tipo De Letra Ydiferentes Tamaños a Itens De Un Combobox
 
Holaforo como andan espero que bien bueno hoy tengo una duda y es como hago para colocar los Itens de un combobox de diferentes tamaños y diferentes tipos de letra espero su respuesta gracias de antemano gulder-gan

maeyanes 24-11-2008 15:47:56

Hola...

El nombre correcto de la propiedad que mencionas es IteMs.

Para lograr lo que deseas tienes que establecer la propiedad Style del ComboBox en csOwnerDrawFixed o csOwnerDrawVariable y usa los eventos OnDrawItem y/o OnMeasureItem.

Para mayor información usa la ayuda de Delphi.


Saludos...

Caro 24-11-2008 16:02:28

Hola gulder, como te dice mayanes tienes que utilizar el evento OnDrawItem del ComBoBox y su propiedad Style en csOwnerDrawFixed.

Este ejemplo te pinta el item 1 y 4, tu debes establecer tu condición.

Código Delphi [-]
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
 With ComboBox1 do
  begin
   if (Index=1) or (Index=4) then
    begin
     Canvas.Font.Name := 'Verdana';
     Canvas.Font.Color := clRed;
     Canvas.Font.Size := 12;
    end
   else
    begin
     Canvas.Font.Name := 'Vivian';
     Canvas.Font.Color := clBlack;
     Canvas.Font.Size := 10;
    end;
   Canvas.FillRect(Rect);
   Canvas.TextOut(Rect.Left + 4, Rect.Top + 1, Items[Index]);
  end;
end;

Mayanes una pregunta, si se le da un tamaño grande que pase el alto que tiene cada item, el texto se corta, ¿como se puede hacer para que el alto del item se adecue al tamaño de letra?.

Saluditos

gulder 24-11-2008 16:16:48

hola como andan maeyanes, Caro gracias por sus respuestas estan muy buenas y me uno a caro en la pregunta que le hace la cual es la siguientes

Mayanes una pregunta, si se le da un tamaño grande que pase el alto que tiene cada item, el texto se corta, ¿como se puede hacer para que el alto del item se adecue al tamaño de letra?.


saludos gulder-gan y gracias

maeyanes 24-11-2008 16:28:55

Hola...

Para eso es el valor csOwnerDrawVariable, junto con los eventos OnMeasureItem y OnDrawItem.

Con el evento OnMeasureItem estableces el alto del item en pixeles.

Un pequeño ejemplo:

Código Delphi [-]
procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index:
  Integer; var Height: Integer);
begin
  Height := Control.Canvas.GetTextHeight(ComboBox1.Items[Index])
end;


Saludos...

gulder 24-11-2008 16:34:20

bueno maeyanes me salio un error me dice que canvas no esta declarada o algo asi saludoes men

Caro 24-11-2008 18:04:27

Cita:

Empezado por maeyanes (Mensaje 327609)
Para eso es el valor csOwnerDrawVariable, junto con los eventos OnMeasureItem y OnDrawItem.

Con el evento OnMeasureItem estableces el alto del item en pixeles.

Un pequeño ejemplo:

Código Delphi [-]

procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index:
Integer; var Height: Integer);
begin
Height := Control.Canvas.GetTextHeight(ComboBox1.Items[Index])
end;


Saludos...

Hola Mayanes, gracias por responder, acabo de probar lo que dices, pero no me esta funcionando, primero, Control no tiene la propiedad Canvas y Canvas no tiene el GetTextHeigth pero si el TextHeigth, hice lo siguiente, en el evento OnMeasureItem:

Código Delphi [-]
procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);
begin
 if Index<>-1 then //Verificamos para que no nos de un ActionViolation
  Height := Canvas.TextHeight(ComboBox1.Items[Index]);
end;

pero nada, el TextHeigth me devuelve siempre el mismo alto para todos los items y es ese mismo alto que le asigna a Heigth, por si acaso también puse la propiedad Style con csOwnerDrawVariable, ¿me puedes decir en que me estoy equivocando?.

Saluditos...

maeyanes 24-11-2008 18:16:17

Hola...

Bueno, ya que lo mencionas veo que cometí algunos errores... :p

La forma correcta sería:

Código Delphi [-]
procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);
begin
  with TComboBox(Control) do
  begin
    Canvas.Font.Name := Items[Index]; // Obtenemos el nombre de la fuente del mismo ComboBox
    Canvas.Font.Size := 10; // Establecemos el tamaño
    Height := Canvas.TextHeight(Items[Index]) // Ahora si obtenemos la altura correcta
  end
end;


Saludos...

Caro 24-11-2008 18:59:11

Hola de nuevo Mayanes, sigue sin funcionarme, tampoco funciona definiendo el tamaño en el OnMeasureItem (esto con el canvas.font) como en tu ultimo ejemplo, solo aclarar que el OnMeasureItem se ejecuta antes que el OnDrawItem, sera que puedas probarlo con el ejemplo que puse arriba en mi primer mensaje. Otra cosita, lo que te devuelve esto Canvas.TextHeight(Items[Index]); es el alto del ComboBox y al final el alto del texto lo pone con el que esta en diseño, osea no cambia nada.

Saluditos

gulder 24-11-2008 19:08:40

maeyanes que pena con voz pero tampoco me funcio lo del ejemplo men saludes y gacias por estar pendiente del problema

maeyanes 24-11-2008 20:12:26

Hola...

Estuve checando con un pequeño programa de ejemplo y es cierto lo que comentas...

Del lado del evento OnMeasureItem, veo que el valor que devuelve lo usa el componente para establecer su alto y si lo desactivo no se dibujan bien los items.

Del lado del evento OnDrawItem, hay que tener en cuenta el valor del parámetro State para dibujar los diferentes estados.

Aquí los eventos que usé para las pruebas:

Código Delphi [-]
procedure TForm1.cbbFontsDrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  with TComboBox(Control) do
  begin
    if not (odComboBoxEdit in State) then
      Canvas.Font.Size := 15;
    Canvas.Font.Name := Items[Index];
    Canvas.FillRect(Rect);
    Canvas.TextOut(Rect.Left, Rect.Top, Items[index]);
    Canvas.Font.Name := Font.Name;
    Canvas.Font.Size := Font.Size
  end
end;

procedure TForm1.cbbFontsMeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);
var
  AHeight: Integer;
  Bitmap: TBitmap;

begin
  if Index < 0 then
    Exit;
  with TComboBox(Control) do
  begin
    Bitmap := TBitmap.Create;
    try
      Bitmap.Canvas.Font.Name := Items[Index];
      Bitmap.Canvas.Font.Size := 15;
      AHeight := Bitmap.Canvas.TextHeight(Items[Index])
    finally
      Bitmap.Free
    end;
  end;
  Height := AHeight
end;


Saludos...

Lepe 24-11-2008 22:46:07

Me parece que estáis mezclando el canvas del form con el del combo y por eso no os sale igual.

Edito: ahh, ya veo, el error estaba en que en MesureItem le daba un tamaño de fuente de 12 y después al pintar de 15, por eso se mezclaban unos encima de otros.

Por otro lado, cuidadín con el uso de :
Código Delphi [-]
  with TComboBox(Control) do
  begin
    Canvas.Font.Name := Items[Index]; // Obtenemos el nombre de la fuente del mismo ComboBox
    Canvas.Font.Size := 10; // Establecemos el tamaño
    Height := Canvas.TextHeight(Items[Index]) // Ahora si obtenemos la altura correcta
  end

Porque ahí "Height" se refiere al Tcombobox, precisamente por el uso del with Tcombbox(control), cuando en realidad nosotros queremos el nombre del parámetro del evento... ofú lo que me ha salido...

Aquí algo más simple, tiene algún fallito de pintado, pero no me he puesto a ver el brush, el pen que se usa ni el estado del elemento.

yo le he llamado al combo "cbb" a secas.
Código Delphi [-]
procedure TForm1.cbbDrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
    cbb.Canvas.Font.Name := cbb.Items[Index];
    cbb.Canvas.Font.Size:= 15;
    cbb.Canvas.TextOut(Rect.Left, Rect.Top, cbb.Items[index]);
end;

procedure TForm1.cbbMeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);

begin
  if Index < 0 then Exit;
  cbb.Canvas.Font.Name:= cbb.items[index];
  cbb.Canvas.Font.Size:= 15;
  Height := cbb.Canvas.TextHeight(cbb.items[index]);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    cbb.Items.Assign(Screen.Fonts);
end;

Saludos

Caro 26-11-2008 15:09:42

Hola de nuevo, perdon no había visto sus respuestas, muchas gracias por responder Mayanes y Lepe, si funciona, el error que estaba cometiendo era que mis items del ListBox estan cargados desde diseño y de esa forma no se asignan bien los tamaños, si se carga en ejecución los items funciona perfecto. Aplicando al ejemplito de mi primer mensaje y haciendo algunas modificaciones según lo que he visto en sus codigos quedaría así:

Código Delphi [-]
procedure TForm1.ListBox1MeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);
begin
 if ListBox1.items.Count>0 then
  begin
   if (Index=1) or (Index=4) then
    ListBox1.Canvas.Font.Size := 10
   else
    ListBox1.Canvas.Font.Size := 20;
 
   Height := ListBox1.Canvas.TextHeight(ListBox1.items[index]);
  end;
end;
 
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
 if ListBox1.items.Count>0 then
  begin
   if (Index=1) or (Index=4) then
    begin
     ListBox1.Canvas.Font.Name := 'verdana';
     ListBox1.Canvas.Font.Size := 10;
    end
   else
    begin
     ListBox1.Canvas.Font.Name := 'vivian';
     ListBox1.Canvas.Font.Size := 20;
    end;
   ListBox1.Canvas.FillRect(Rect);
   ListBox1.Canvas.TextOut(Rect.Left, Rect.Top, ListBox1.Items[index]);
  end;
end;

Como dije, si se cargan los items en ejecución funciona bien, pero si ya estan cargados los items en dideño, no funciona se sigue cortando el texto, aunque se ejecute dichos eventos. Ahora si hago esto

Código Delphi [-]
 //Enviamos el mensaje de repintar al ListBox
 ListBox1.Perform(WM_Paint, ListBox1.Canvas.Handle, 0);

Si se ve correctamente, pero cuando se selecciona un item sigue con el tamaño del principio y se sobrepone todo.

Pueden hacer la prueba por favor y como sería para solucionar que se de la altura correcta aunque ya este en diseño.

Saluditos

Lepe 26-11-2008 18:46:58

Pues la cosa está bien dificil.

El listbox tiene la propiedad ItemHeight y debe estar establecida al máximo alto posible.

Otra parte del fallo de repintado es mío :o que según veo lo has corregido:
Código Delphi [-]
ListBox1.Canvas.TextRect(Rect, Rect.Left, Rect.Top, ListBox1.Items[index]);

Pero claro, debes conocer de antemano cuan grande será los elementos y cual será el mayor :(

A ver si te sirve, si no, la cosa iría por dibujar tú encima siempre... y no sé que tal se verá :(.

Caro 27-11-2008 13:24:44

Cita:

Empezado por Lepe (Mensaje 328127)
Pues la cosa está bien dificil.

El listbox tiene la propiedad ItemHeight y debe estar establecida al máximo alto posible.

..........

Pero claro, debes conocer de antemano cuan grande será los elementos y cual será el mayor

A ver si te sirve, si no, la cosa iría por dibujar tú encima siempre... y no sé que tal se verá :(.

Hola Lepe, muchas gracias de nuevo por responder, pero si esta dificil, hice mas pruebas pero nada y repintando no se ve bien, creo que lo mejor es que cargue los items en ejecución y listo, así me olvido de repintar y todo eso.

Saluditos

roman 27-11-2008 19:08:39

El problema se debe -al parecer- a que la medida de los ítems se toma una sóla vez y no cada vez que se dibujan, de forma que, si se cargan en diseño, se toma la medida tal como se tiene al momento de cargar el formulario, que vendría siendo el tamaño de la fuente asignada al ListBox.

Una solución, no muy elegante, por cierto, es forzar el recreado del control; por ejemplo, en el OnCreate del formulario:

Código Delphi [-]
type
  THack = class(TListBox);

procedure TForm1.FormCreate(Sender: TObject);
begin
  THack(ListBox1).RecreateWnd;
end;

// Saludos

Caro 28-11-2008 14:47:40

Cita:

Empezado por roman (Mensaje 328402)
El problema se debe -al parecer- a que la medida de los ítems se toma una sóla vez y no cada vez que se dibujan, de forma que, si se cargan en diseño, se toma la medida tal como se tiene al momento de cargar el formulario, que vendría siendo el tamaño de la fuente asignada al ListBox.

Una solución, no muy elegante, por cierto, es forzar el recreado del control; por ejemplo, en el OnCreate del formulario:

Hola Roman, aunque no sea muy elegante pero si funciona, muchas gracias.

Saluditos


La franja horaria es GMT +2. Ahora son las 16:15:29.

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