Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   ImageList en ListBox.Columns:=1 (https://www.clubdelphi.com/foros/showthread.php?t=81659)

bulc 04-12-2012 19:39:52

ImageList en ListBox.Columns:=1
 
Hola. Estoy intentando colocar una imagen (de un ImageList) a la izquierda del texto de un ListBox. El ListBox se mueve en horizontal para lo que asigno 1 a la prop. Columns. El problema es que en el Canvas del ListBox no quedan bien alineados Imagen-Texto. Las imágenes se agolpan unas sobre otras. Aunque de las cinco que tengo la primera, "casi" queda bien. Me gustaría cargar
unas treinta imágenes de unos 60x40 píxeles para que aparezca una secuencia de imagen+ palabra en cada clic de ratón sobre las flechas del ListBox.
Sigo este código pero un poco a ciegas porque no entiendo bien el proceso.
Código Delphi [-]
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
with (Control as TListBox) do
begin
Canvas.FillRect(Rect); //Carga las coordenadas del TListBox.   
Canvas.TextOut( Rect.Left +ImageList1.Height+2,  Rect.Top,  Items[Index]); //??
ImageList1.Draw(Canvas,  Rect.Left,  Rect.Top, Index); //??
end;
end;
A ver si algún apóstol de Delphi me ilumina. Gracias

nlsgarcia 04-12-2012 21:47:08

bulc,

Revisa esta imagen:



Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ImgList, ImgListBox, ImgComboBox, Buttons;

type
  TForm1 = class(TForm)
    ImgComboBox1: TImgComboBox;
    ImgListBox1: TImgListBox;
    ImageList1: TImageList;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure ImgListBox1Click(Sender: TObject);
    procedure ImgComboBox1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BitBtn1Click(Sender: TObject);
var
   i : Integer;
begin
   ImgListBox1.Clear;
   ImgListBox1.Images := ImageList1;
   for i := 0 to 4 do
   begin
      ImgListBox1.SetImageIndex(i,i);
      ImgListBox1.Items.Add('ImgListBox-'+IntToStr(i));
   end
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
var
   i : Integer;
begin
   ImgComboBox1.Clear;
   ImgComboBox1.Images := ImageList1;
   for i := 0 to 4 do
   begin
      ImgComboBox1.SetImageIndex(i,i);
      ImgComboBox1.Items.Add('ImgComboBox-'+IntToStr(i));
   end
end;

procedure TForm1.ImgListBox1Click(Sender: TObject);
begin
   ShowMessage(ImgListBox1.Items.Strings[ImgListBox1.ItemIndex]);
end;

procedure TForm1.ImgComboBox1Change(Sender: TObject);
begin
   ShowMessage(ImgComboBox1.Items.Strings[ImgComboBox1.ItemIndex]);
end;

end.
El código anterior implementa los componentes freeware TImgComboBox y TImgListBox creados por Derek van Daal : derekvandaal@hotmail.com

El ejemplo y el componente se encuentran en el link: http://terawiki.clubdelphi.com/Delph...ImgListBox.rar

La información original fue obtenida del link: http://www.delphipages.com/comp/imag...ist_-4580.html

Espero sea útil :)

Nelson.

nlsgarcia 04-12-2012 23:49:40

bulc,

Component Information:
Cita:

Derived from TComboBox and TListBox respectively. Both with the following added:

Properties:
-Images - Select an ImageList for using its images, for example:
ImgListBox1.Images := ImageList1;

-TransparentColor
- Select the color to display as transparent in the combobox

Procedure:
-SetImageIndex(ItemIndex : Integer; ImageIndex : Integer) - Sets the ImageIndex of a specific item, for example:
ImgComboBox1.SetImageIndex(0,12); This will Set the ImageIndex of Item number 0 in the ImgComboBox to 12
Espero sea útil :)

Nelson.

ecfisa 05-12-2012 03:00:38

Cita:

Empezado por bulc (Mensaje 451245)
El problema es que en el Canvas del ListBox no quedan bien alineados Imagen-Texto. Las imágenes se agolpan unas sobre otras.

Hola bulc.

O estoy entendiendo mal tu problema, o la solución es ajustar la propiedad ItemHeight del ListBox a la altura de las imágenes al inicio:
Código Delphi [-]
  ListBox1.ItemHeight := ImageList1.Height;

Por ejemplo:
Código Delphi [-]
...
procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  with ListBox1 do
  begin
    Columns:= 1;
    Style:= lbOwnerDrawFixed;
    for i:= 0 to 9 do
      Items.Add('Item '+IntToStr(i));
    Font.Size := 24;  // tamaño font a gusto
    ItemHeight:= ImageList1.Height; // en el ejemplo: 48x48
  end;
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  with TListBox(Control) do
  begin
    Canvas.FillRect(Rect);
    ImageList1.Draw(Canvas,  Rect.Left,  Rect.Top, Index);
    Canvas.TextOut(Rect.Left + ImageList1.Width + 10,
      ((Rect.Top+Rect.Bottom)div 2)-(Font.Size div 2), Items[Index]);
  end;
end;
...
Da este resultado:



Saludos.

bulc 05-12-2012 16:15:25

Me lo estudio
 
No sé como sabéis tanto. Gracias.

bulc 05-12-2012 16:18:46

Canvas.TextOut
 
Cita:

Empezado por ecfisa (Mensaje 451267)
Hola bulc.

O estoy entendiendo mal tu problema, o la solución es ajustar la propiedad ItemHeight del ListBox a la altura de las imágenes al inicio:
Código Delphi [-]
  ListBox1.ItemHeight := ImageList1.Height;

Por ejemplo:
Código Delphi [-]
...
procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  with ListBox1 do
  begin
    Columns:= 1;
    Style:= lbOwnerDrawFixed;
    for i:= 0 to 9 do
      Items.Add('Item '+IntToStr(i));
    Font.Size := 24;  // tamaño font a gusto
    ItemHeight:= ImageList1.Height; // en el ejemplo: 48x48
  end;
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  with TListBox(Control) do
  begin
    Canvas.FillRect(Rect);
    ImageList1.Draw(Canvas,  Rect.Left,  Rect.Top, Index);
    Canvas.TextOut(Rect.Left + ImageList1.Width + 10,
      ((Rect.Top+Rect.Bottom)div 2)-(Font.Size div 2), Items[Index]);
  end;
end;
...
Da este resultado:



Saludos.

Si tienes tiempo, ¿podrías explicar este punto (Canvas.TextOut)? Gracias.

ecfisa 05-12-2012 20:06:41

Hola bulc.

Hice ese cácluculo para centrar verticalmente el texto de forma aproximada.

La mitad del alto es Rect.Top+Rect.Bottom div 2 y ya que están igualados, también se podría haber usado ImageList1.Height div 2.
Código:

  +----------+ Top
  |          |
  |----------| Top+Bottom / 2   
  |          | 
  +----------+ Button

Del mismo modo el font se divide a la mitad para acomodarse al centro. En ese momento no me acordé pero mucho mas exácto es usar:
Código Delphi [-]
 Canvas.TextOut(Rect.Left + ImageList1.Width + 10,
      (ImageList1.Height div 2)-(Canvas.TextHeight(Items[Index]) div 2), Items[Index]);

Saludos.

nlsgarcia 05-12-2012 22:01:31

bulc,

La solución de Ecfisa es excelente, sin embargo te sugiero revisar los componentes TImgComboBox y TImgListBox creados por Derek van Daal dado que facilitan el uso de imágenes y permiten la creación de un código más simple y directo.

Espero sea útil :)

Nelson.

bulc 06-12-2012 16:46:05

Cita:

Empezado por nlsgarcia (Mensaje 451316)
bulc,

La solución de Ecfisa es excelente, sin embargo te sugiero revisar los componentes TImgComboBox y TImgListBox creados por Derek van Daal dado que facilitan el uso de imágenes y permiten la creación de un código más simple y directo.

Espero sea útil :)

Nelson.

Gracia a ambos. Voy a colocarlo en mi aplicación a ver qué tal.... Hasta pronto.


La franja horaria es GMT +2. Ahora son las 21:33:47.

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