Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Aspecto de un combobox (https://www.clubdelphi.com/foros/showthread.php?t=91479)

Angel.Matilla 15-02-2017 14:04:30

Aspecto de un combobox
 
¿Existe la posibilidad de cambiar la altura de un TComboBox? Ahora mismo tengo varios puestos en un formulario pero por más que lo intento no puedo reducir la altura y el aspecto que queda es bastante feo porque los combos son más grandes que los TEdit que hay en el resto del formulario.

Caminante 15-02-2017 17:49:09

Hola

Hasta donde yo recuerdo la unica solucion era cambiar el tamaño de fuente del control ya que cambiar el tamaño del componente no surtia efecto.

Saludos

aguml 15-02-2017 21:04:35

Lo más fácil seria cambiar el tamaño de los TEdits para que tengan el tamaño de los TComboBoxs.
Lo difícil es lo que intentas aunque imposible no creo que sea. Prueba a ver si esto te sirve: http://forums.codeguru.com/showthrea...-designer-view

roman 15-02-2017 22:26:10

Tal como indica aguml, puedes usar un combobox "ownerdraw", o sea con su propiedad Style en csOwnerDrawFixed. Con eso, ajustando la propiedad ItemHeight obtienes la altura deseada para el combo. Sin embargo, el texto de cada item queda pegado al borde superior y se ve un poco feo. Para centrarlo tienes que implementar el evento OnDrawItem:

Código Delphi [-]
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  with (Control as TCustomComboBox) do
  begin
    Canvas.FillRect(Rect);
    InflateRect(Rect, -2, 0);
    Windows.DrawText(Canvas.Handle, PChar(Items[Index]), -1, Rect, DT_SINGLELINE or DT_VCENTER);
  end;
end;

LineComment Saludos

ecfisa 15-02-2017 22:31:27

Hola.

No se si te sirva pero, de forma similar al enlace que puso aguml un ejemplo usando las propiedades ItemHeight y Height para lograr el cometido:

Código PHP:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
   
ComboBox1->Style     csOwnerDrawVariable;
   
ComboBox1->ItemIndex 0;
}

void __fastcall TForm1::ReduceClick(TObject *Sender)
{
  
ComboBox1->ItemHeight ComboBox1->ItemHeight 2;
  
ComboBox1->Height     ComboBox1->Height 1;
}

void __fastcall TForm1::btnIncreaseClick(TObject *Sender)
{
  
ComboBox1->ItemHeight ComboBox1->ItemHeight 2;
  
ComboBox1->Height     ComboBox1->Height 1;


Efecto:


Saludos :)

Edito: Y agregando la rutina de roman (que no había visto al momento de este), ciertamente queda mucho mejor presentado.

roman 15-02-2017 22:35:15

Cita:

Empezado por Angel.Matilla (Mensaje 513302)
porque los combos son más grandes que los TEdit que hay en el resto del formulario.

Por otro lado, ¿cómo es posible esto? Es decir, por defecto los combos y los edit son del mismo tamaño (altura) que está dado por el tamaño de la fuente de caracteres. Si cambias la fuente del combo a que sea igual a la que usas en los edit, se verían similares ¿no?

LineComment Saludos

AgustinOrtu 16-02-2017 00:25:11

Usando las ideas de roman y ecfisa

No he cambiado ninguna propiedad en tiempo de diseño, todo lo hago en ejecucion

Código Delphi [-]
procedure TForm2.FormCreate(Sender: TObject);
begin
  ComboBox1.Style := TComboBoxStyle.csOwnerDrawFixed;
  ComboBox1.OnDrawItem := ComboBox1DrawItem;
  ComboBox1.Font.Size := 14;
  ComboBox1.Canvas.Font.Size := 14;
  ComboBox1.ItemHeight := ComboBox1.Canvas.TextHeight('|') + 2;
  // cargo el combo con la lista de fuentes del sistema para ver como queda
  ComboBox1.Items := Screen.Fonts;
  ComboBox1.ItemIndex := 0;
end;

procedure TForm2.ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
  Target: TComboBox absolute Control;
begin
  Target.Canvas.FillRect(Rect);
  if (Index >= 0) and (Index < Target.Items.Count) then
  begin
    if ([odComboBoxEdit, odSelected] * State = [odComboBoxEdit, odSelected]) then
      Target.Canvas.Font.Color := clHighlightText;

    Target.Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Target.Items[Index]);
  end;
end;

// lo que sigue es el codigo de los botones
procedure TForm2.btnIncreaseClick(Sender: TObject);
begin
  ComboBox1.Font.Size := ComboBox1.Font.Size + 1;
  ComboBox1.Canvas.Font.Size := ComboBox1.Canvas.Font.Size + 1;
  ComboBox1.Height := ComboBox1.Height - 1;
  ComboBox1.ItemHeight := ComboBox1.Canvas.TextHeight('|') + 2;
end;

procedure TForm2.btnReduceClick(Sender: TObject);
begin
  ComboBox1.Font.Size := ComboBox1.Font.Size - 1;
  ComboBox1.Canvas.Font.Size := ComboBox1.Canvas.Font.Size - 1;
  ComboBox1.Height := ComboBox1.Height + 1;
  ComboBox1.ItemHeight := ComboBox1.Canvas.TextHeight('|') + 2;
end;



Edito: Probando me estoy dando cuenta de que el evento OnDrawItem no es estrictamente necesario:

Cita:

If an OnDrawItem event handler is not provided, the combo box fills the Rect parameter with the current brush and writes the text value of the item specified by the Index parameter.

Angel.Matilla 16-02-2017 11:28:00

Gracias por vuestras respuestas. Me ha sido útiles pero al final me dieron una solución que creo más sencilla: Poner en el constructor del formulario
Código:

SendMessage(ComboBox1->Handle, CB_SETITEMHEIGHT, -1, <altura en píxeles>);

roman 16-02-2017 16:43:32

Cita:

Empezado por AgustinOrtu (Mensaje 513329)
Edito: Probando me estoy dando cuenta de que el evento OnDrawItem no es estrictamente necesario:

Así es, pero tal como comenté en el mensaje, el texto no queda centrado verticalmente ;)

LineComment Saludos

roman 16-02-2017 16:46:17

Cita:

Empezado por Angel.Matilla (Mensaje 513346)
Gracias por vuestras respuestas. Me ha sido útiles pero al final me dieron una solución que creo más sencilla: Poner en el constructor del formulario
Código:

SendMessage(ComboBox1->Handle, CB_SETITEMHEIGHT, -1, <altura en píxeles>);

Pues sí que es sencilla. Pero más sencilla es cambiar la propiedad ItemHeight, tal como te habíamos dicho :p

LineComment Saludos

Angel.Matilla 16-02-2017 18:13:02

Cita:

Empezado por roman (Mensaje 513357)
Pues sí que es sencilla. Pero más sencilla es cambiar la propiedad ItemHeight, tal como te habíamos dicho :p

El probela de esta solcuión es que los elementos pueden llegara a amontonarse al desplegar el combo.

roman 16-02-2017 18:32:04

Y de la otra forma, ¿cómo queda? ¿Puedes poner una imagen?

LineComment Saludos

Angel.Matilla 16-02-2017 18:45:43

Cita:

Empezado por roman (Mensaje 513377)
Y de la otra forma, ¿cómo queda? ¿Puedes poner una imagen?

Pues lo cierto es que la diferencia es menor de lo que me había parecido. Probaré porque tal vez sea mejor solución.

roman 16-02-2017 18:54:25

Pues sí. Es que, a fin de cuentas, si no cabe, no cabe :D Independientemente del método.

LineComment Saludos

AgustinOrtu 16-02-2017 19:14:51

Cita:

Empezado por roman (Mensaje 513379)
Así es, pero tal como comenté en el mensaje, el texto no queda centrado verticalment

Tenes razon, me pregunto porque lo habran implementado de esa manera. Aunque tuve que hacerme este ejemplo para darme cuenta :D


_Leo 16-02-2017 23:08:08

Cita:

Empezado por Angel.Matilla (Mensaje 513378)
Pues lo cierto es que la diferencia es menor de lo que me había parecido. Probaré porque tal vez sea mejor solución.

Use SendMessage intencionadamente porque solo cambia el alto del Combo y no de los elementos, pero claro si quieres que también cambie la altura de los distintos elementos lo mejor es lo que comenta Román más arriba. Son igualmente un par de líneas, y opcionalmente el DrawItem para que se muestre el texto centrado verticalmente.

roman 16-02-2017 23:38:07

Ahora que lo mencionas, me parece que hay un problema con la solución del SendMessage. En Delphi 7 al menos, al desplegar el combo la VCL lo regresa a su estado inicial.

LineComment Saludos

_Leo 17-02-2017 00:02:58

Cita:

Empezado por roman (Mensaje 513413)
Ahora que lo mencionas, me parece que hay un problema con la solución del SendMessage. En Delphi 7 al menos, al desplegar el combo la VCL lo regresa a su estado inicial.

LineComment Saludos

En C++Builder va bien, probado en las versiones 1, 4, 6, 2010, XE4 y 10.1, por lo menos ese problema que comentas.

(Aunque Angel no lo menciona, antes del SendMessage hay que poner la propiedad Style a csOwnerDrawVariable)

roman 17-02-2017 16:20:54

Cita:

Empezado por _Leo (Mensaje 513414)
(Aunque Angel no lo menciona, antes del SendMessage hay que poner la propiedad Style a csOwnerDrawVariable)

Esto es lo que faltaba. Con ello desaparece el problema que veía :)

LineComment Saludos

aguml 17-02-2017 18:02:19

Supongo que para que no se amontonen puedes reducir el número de Items que se muestran. Por defecto son 8.


La franja horaria es GMT +2. Ahora son las 10:23:24.

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