• identificar y agregar iconos de discos en combobox

 #486183  por joselin
 13 May 2016, 10:09
buenas, habra alguna forma de dibujar los iconos de una manera mas practica
en el proyecto simulo la llegada de las letras de las unidades y en otra cadena recibira el drivetype para identificarlos y agregar el icono correcto
en el combobox
(en imagelist1 tengo los 3 iconos de disco )
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ImgList,shellapi, ExtCtrls;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    ImageList1: TImageList;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    ImageList2: TImageList;
    procedure Button2Click(Sender: TObject);

    procedure ComboBox1DrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
  private
  str:tstringlist;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

      //simulando lectura y dibujo de icono de discos logicos de conexion cliente server  para filemanager
      { 0 = Unknown
1 = No Root Directory
2 = Removable Disk
3 = Local Disk
4 = Network Drive
5 = Compact Disc
6 = RAM Disk }

procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
iconicof:ticon;
begin
  //suponiendo que el server me manda los datos  de letra de unidad y aparte lel drivetype de cada uno
  //intento colocar el icono corecto en un combobox
combobox1.Clear;
str:=tstringlist.create;
   iconicof:= TIcon.Create;
 str.add( 'Removable Disk');
 str.add( 'Local Disk');
 str.add( 'Local Disk');
 str.add( 'Removable Disk');
 str.add( 'Compact Disc');
 str.add( 'Compact Disc');


 ComboBox1.Items.Add('A:\');
  ComboBox1.Items.Add('C:\');
  ComboBox1.Items.Add('F:\');
  ComboBox1.Items.Add('G:\');
  ComboBox1.Items.Add('H:\');
  ComboBox1.Items.Add('I:\');







   for i:=0 to str.Count -1 do begin
      if str.strings[i] =  'Local Disk' then
      imagelist1.GetIcon(0,iconicof);
     if str.strings[i] =  'Removable Disk' then
      imagelist1.GetIcon(1,iconicof);
        if str.strings[i] =  'Compact Disc' then
        imagelist1.GetIcon(2,iconicof);

       imagelist2.addicon(iconicof);

        end;

         iconicof.Free;
            str.Free;



      end;


procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);

var
    AnIcon : TIcon;

begin
    AnIcon := TIcon.Create;
    try


      with Control as TComboBox do begin

             form1.ImageList2.GetIcon (index,AnIcon);
             //dibuja el icono
           Canvas.Draw (Rect.Left,Rect.Top,AnIcon);
            //dibuja el texto que precede al icono
          Canvas.TextOut (Rect.Left + form1.ImageList2.Width,Rect.Top,Items[Index]);


        end;


    finally
        AnIcon.Free;
    end;

       END;

end.
 #486184  por sanko
 13 May 2016, 14:41
Yo no sé pascal, pero normalmente cuando queremos usar componentes personalizados y sabemos que vamos a reusarlos mucho en el proyecto, generalmente se crea un wrapper de la clase, en este caso un wrapper (una clase que extienda o implemente) la clase/interfaz combobox, a la que le podrás añadir las restricciones, iconos o demás cosas personalizadas, luego sencillamente en lugar de usar combobox en tu proyecto, usarias los wrappers.

Cómodo y sensillo para todos los publicos y publicas.
 #486228  por joselin
 15 May 2016, 02:07
gracias sanko voy a ver que encuentro de wrappers en delphi
al tener poca nocion de programacion, a veces le doy mil vueltas a un codigo,
queda funcional pero te come media maquina en recursos,
a veces usando tres lines se resuelve el problema.
 #486235  por joselin
 15 May 2016, 11:20
hi pink yo intente hacer en un solo imagelist
la asignacion de iconos segun el tipo de unidad y no pude
controlar la propiedad draw del combobox
el contexto del codigo se daria en una conexion inversa donde recibo las letras de las unidades
y el tipo de disco que es , y asi le asigno desde el cliente el icono correspondiente

cliente<-------------------------------------string(c:\lLocal Disk|d:\Removable Disk')----------------------------------server
asignamos el icono
 #486236  por joselin
 15 May 2016, 11:26
//recibimos los discos
     if copy (datos,1,11) ='<|Drivers|>' then  begin
     datosFileManager := datos;

     Delete(datosFileManager, 1, Pos('<|Drivers|>', datosFileManager)+10);//borramos indicador1
     Delete(datosFileManager, Pos('<<|Drivers|>>', datosFileManager),13);//borramos indicador2

       t:=tstringlist.Create;
       t.text:= datosFileManager;
       for i:=0 to t.count -1 do begin
       discos:= discos+copy(t[i],0,3)+#13;
       tipos:= tipos+copy(t[i],pos('\',t[i])+1,length(t[i])-1)+#13;
     end;
    T.Free;

   ComboBox1.Items.Text := discos;

   icondr:=tstringlist.Create;
   iconicof:= TIcon.Create;
   icondr.Text:=tipos;

   for i:=0 to icondr.Count -1 do begin
      if icondr.strings[i] =  'FIXED' then
      imagelist2.GetIcon(0,iconicof);
     if icondr.strings[i] =  'REMOVABLE' then
      imagelist2.GetIcon(1,iconicof);
        if icondr.strings[i] =  'CDROM' then
        imagelist2.GetIcon(2,iconicof);

       imagelist3.addicon(iconicof);

        end;

         iconicof.Free;
            icondr.Free;
y en el combobox
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
    AnIcon : TIcon;
begin
    AnIcon := TIcon.Create;
    try
        form1.ImageList3.GetIcon (Index,AnIcon);
        with Control as TComboBox do begin
            Canvas.Draw (Rect.Left,Rect.Top,AnIcon);
            Canvas.TextOut (Rect.Left + form1.ImageList3.Width,Rect.Top,Items[Index]);
        end;
    finally
        AnIcon.Free;
    end

end;
estoy buscando algo mas simple