Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 09-04-2008
Avatar de lag_0
lag_0 lag_0 is offline
Miembro
 
Registrado: jul 2006
Posts: 131
Poder: 18
lag_0 Va por buen camino
TListview y añadir elementos...

Buenas!!
Pues nada, tengo un codigo que me va LENTISIMO y todo en la parte en la que añado los elementos a mi TListview...

Lo hago así:
Código Delphi [-]
var
  TempI,TempII,foundby:integer;
  tempb:bool;
  filtrados:integer;
  TempSna,TempSdn,TempSip,TempSmo:string;
  TiT : TListItem;
begin
  //Mostramos la DB
    AllStatus(False);
    filtrados := 0;
    comparacionaeservista.Clear;
    for TempI := 0 to aerodbreplist.Items.Count-1 do begin
      application.ProcessMessages;
      foundby := -1;
      TempSna := aerodbreplist.Items.Item[TempI].Caption;
      TempSdn := aerodbreplist.Items.Item[TempI].SubItems.Strings[0];
      TempSip := aerodbreplist.Items.Item[TempI].SubItems.Strings[1];
      TempSmo := aerodbreplist.Items.Item[TempI].SubItems.Strings[2];
      TempII:=0;
      while TempII < getsoksek.Items.count do begin
        if TraduceSMtoDB('i',TempSip,getsoksek.Items.Item[TempII].SubItems.Strings[1]) then begin
          foundby := TempII;
          TempII := getsoksek.items.count;
        end else if TraduceSMtoDB('d',TempSdn,getsoksek.Items.Item[TempII].SubItems.Strings[0])  then  begin
          foundby := TempII;
          TempII := getsoksek.items.count;
        end else if TraduceSMtoDB('n',TempSNA,getsoksek.Items.Item[TempII].Caption)  then begin
          foundby := TempII;
          TempII := getsoksek.items.count;
        end;
        TempII := TempII + 1;
      end;
      if foundby > -1 then begin
        TiT := comparacionaeservista.Items.Add;
        TiT.Caption := aerodbreplist.Items.Item[TempI].Caption;
        Tit.SubItems.Add(getsoksek.Items.Item[foundby].Caption);
        Tit.SubItems.Add(aerodbreplist.Items.Item[TempI].SubItems.Strings[0]);
        Tit.SubItems.Add(getsoksek.Items.Item[foundby].SubItems.Strings[0]);
        Tit.SubItems.Add(aerodbreplist.Items.Item[TempI].SubItems.Strings[1]);
        Tit.SubItems.Add(getsoksek.Items.Item[foundby].SubItems.Strings[1]);
        Tit.SubItems.Add(aerodbreplist.Items.Item[TempI].SubItems.Strings[2]);
        Tit.SubItems.Add(getsoksek.Items.Item[foundby].SubItems.Strings[2]);
        Tit.SubItems.Add(aerodbreplist.Items.Item[TempI].SubItems.Strings[3]);
        Tit.SubItems.Add(getsoksek.Items.Item[foundby].SubItems.Strings[3]);
        Tit.SubItems.Add(getsoksek.Items.Item[foundby].SubItems.Strings[4]);
        Tit.SubItems.Add('');
      end else begin
        TiT := comparacionaeservista.Items.Add;
        TiT.Caption := aerodbreplist.Items.Item[TempI].Caption;
        Tit.SubItems.Add('N/A');
        Tit.SubItems.Add(aerodbreplist.Items.Item[TempI].SubItems.Strings[0]);
        Tit.SubItems.Add('N/A');
        Tit.SubItems.Add(aerodbreplist.Items.Item[TempI].SubItems.Strings[1]);
        Tit.SubItems.Add('N/A');
        Tit.SubItems.Add(aerodbreplist.Items.Item[TempI].SubItems.Strings[2]);
        Tit.SubItems.Add('N/A');
        Tit.SubItems.Add(aerodbreplist.Items.Item[TempI].SubItems.Strings[3]);
        Tit.SubItems.Add('N/A');
        Tit.SubItems.Add('N/A');
        Tit.SubItems.Add('');
      end;
    end;
[etc...]

No tengo ni idea como puedo hacerlo mas rapido el Tit.... pero es tremendamente lento ... Y por cierto, el primer while es MUY rapido así que no me digais que será por eso por que no... tengo más que debugeado que el retardo enorme está en la parte de "TiT := comparacionaeservista.Items.Add;"...
Hay otra forma mejor? Gracias!!

Vale, si, ya se que hago muchos "application.ProcessMessages;", pero cuando no los hago va igual de lentro y además necesito hacerlo por que no puedo dejar la aplicación en modo colgado...

Muchas gracias...

Última edición por lag_0 fecha: 09-04-2008 a las 15:28:24.
Responder Con Cita
  #2  
Antiguo 09-04-2008
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 23
maeyanes Va por buen camino
Hola...

Prueba haciendo:

Código Delphi [-]
var
  TempI,TempII,foundby:integer;
  tempb:bool;
  filtrados:integer;
  TempSna,TempSdn,TempSip,TempSmo:string;
  TiT : TListItem;
begin
  //Mostramos la DB
  AllStatus(False);
  filtrados := 0;
  comparacionaeservista.Items.BeginUpdate; // Le pedimos al ListView que no refresque 
  // los items...
  try
    comparacionaeservista.Clear;
    // Todo tu código
  finally
    comparacionaeservista.Items.EndUpdate // Le pedimos al ListView que refresque todos
    // los items...
  end
end;


Saludos...
Responder Con Cita
  #3  
Antiguo 10-04-2008
Avatar de lag_0
lag_0 lag_0 is offline
Miembro
 
Registrado: jul 2006
Posts: 131
Poder: 18
lag_0 Va por buen camino
Nada T__________T igual de lento a nadie se le ocurre otra posible solución porfavor ?

Muchas Gracias de todos modos maeyanes...

Última edición por lag_0 fecha: 10-04-2008 a las 15:53:04.
Responder Con Cita
  #4  
Antiguo 10-04-2008
Avatar de ixMike
ixMike ixMike is offline
Miembro
 
Registrado: feb 2004
Posts: 1.151
Poder: 22
ixMike Va por buen camino
Ains....

Código Delphi [-]
begin
ListView1.Items.BeginUpdate;
//Aquí el código de añadir los datos
ListView1.Items.EndUpdate;
end;

Es una faena no conocerse esos métodos También están en ListBox.Items... y creo que en todo lo que se llama "Items".


Salu2



Edito: vale, no sé cómo no vi la respuesta de maeyanes


Añado: ¿y si quitas el ProcessMessages?

Última edición por ixMike fecha: 10-04-2008 a las 16:21:15. Razón: ceguera
Responder Con Cita
  #5  
Antiguo 10-04-2008
Avatar de lag_0
lag_0 lag_0 is offline
Miembro
 
Registrado: jul 2006
Posts: 131
Poder: 18
lag_0 Va por buen camino
Cita:
Empezado por ixMike Ver Mensaje
Ains....


Código Delphi [-]
begin
ListView1.Items.BeginUpdate;
//Aquí el código de añadir los datos
ListView1.Items.EndUpdate;
end;





Es una faena no conocerse esos métodos También están en ListBox.Items... y creo que en todo lo que se llama "Items".


Salu2



Edito: vale, no sé cómo no vi la respuesta de maeyanes


Añado: ¿y si quitas el ProcessMessages?
Ni con esas, con proces o sin el igual de lento, pero de todos modos lo necesito
Responder Con Cita
  #6  
Antiguo 10-04-2008
keyboy keyboy is offline
Miembro
 
Registrado: oct 2004
Posts: 367
Poder: 20
keyboy Va por buen camino
¿De cuántos itemes estamos hablando? Cuando se manejan muchos elementos (y muchos pueden ser unas decenas) estos controles funcionan mucho mejor en modo virtual. Si alguna vez has utilizado un DBGrid, por ejemplo, notarás que su rendimiento es óptimo independientemente de si tienes miles o millones de registros. Pero eso es así porque el componente realmente no guarda toda la información sino que solicita (al DataSet en el caso del DBGrid) sólo los registros que requiere mostrar en un momento dado, esto es, básicamente, sólo los que caben en la parte visual del control.

El ListView puede funcionar en modo virtual poniendo su propiedad OwnerData en true. En esta modalidad, uno no llena explícitamente el control con llamadas a Items.Add. Lo único que se le indica al control de inicio, es el número de elementos que debe manejar:

Código Delphi [-]
ListView.Items.Count := NumeroDeElementos;

Conforme nos desplazamos por la lista, el control solicita la información en el evento OnData:

Código Delphi [-]
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin

end;

El Item que se pasa como parámetro únicamente contiene un dato útil: Item.Index, el índice del elemento que debe proporcionarse.

Entonces, puedes guardar la información en una estructura más eficiente, como un TObjectList, dependiendo del tipo de datos que tengas. Con el Item.Index buscas el elemento que corresponda en tu estructura de datos y con eso llenas la información restante del objeto Item. Por decir algo:

Código Delphi [-]
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := TMiClase(MiLista[Item.Index]).Propiedad;
end;

Espero que esto ayude.

Bye
Responder Con Cita
  #7  
Antiguo 11-04-2008
Avatar de lag_0
lag_0 lag_0 is offline
Miembro
 
Registrado: jul 2006
Posts: 131
Poder: 18
lag_0 Va por buen camino
Cita:
Empezado por keyboy Ver Mensaje
¿De cuántos itemes estamos hablando? Cuando se manejan muchos elementos (y muchos pueden ser unas decenas) estos controles funcionan mucho mejor en modo virtual. Si alguna vez has utilizado un DBGrid, por ejemplo, notarás que su rendimiento es óptimo independientemente de si tienes miles o millones de registros. Pero eso es así porque el componente realmente no guarda toda la información sino que solicita (al DataSet en el caso del DBGrid) sólo los registros que requiere mostrar en un momento dado, esto es, básicamente, sólo los que caben en la parte visual del control.

El ListView puede funcionar en modo virtual poniendo su propiedad OwnerData en true. En esta modalidad, uno no llena explícitamente el control con llamadas a Items.Add. Lo único que se le indica al control de inicio, es el número de elementos que debe manejar:


Código Delphi [-]
ListView.Items.Count := NumeroDeElementos;





Conforme nos desplazamos por la lista, el control solicita la información en el evento OnData:


Código Delphi [-]
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin

end;





El Item que se pasa como parámetro únicamente contiene un dato útil: Item.Index, el índice del elemento que debe proporcionarse.

Entonces, puedes guardar la información en una estructura más eficiente, como un TObjectList, dependiendo del tipo de datos que tengas. Con el Item.Index buscas el elemento que corresponda en tu estructura de datos y con eso llenas la información restante del objeto Item. Por decir algo:


Código Delphi [-]
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := TMiClase(MiLista[Item.Index]).Propiedad;
end;





Espero que esto ayude.

Bye
Gracias por la sugerencia.. Cuando enga un rato lo probaré, puede que tengas razón y sea por lo de los elementos.. nosé son unos 600 o así...

Muchas gracias y un saludo.
Responder Con Cita
  #8  
Antiguo 11-04-2008
jorge82 jorge82 is offline
Baneado
 
Registrado: jun 2005
Ubicación: Mérida, Yucatán, México
Posts: 75
Poder: 19
jorge82 Va por buen camino
Revisa la siguiente liga: http://www.marteens.com/trick31.htm.
En ella Ian Marteens da unos consejos para cargar datos en un ListView.
Espero te ayude.
Responder Con Cita
  #9  
Antiguo 15-04-2008
Avatar de lag_0
lag_0 lag_0 is offline
Miembro
 
Registrado: jul 2006
Posts: 131
Poder: 18
lag_0 Va por buen camino
Nada...no hay forma humana... esto va lento a más no poder, como 3 minutos para poner todos los items en mi portatil y en un servidor con 4 CPU's, 4 GB's de RAM etc etc (vamos la hostia) tarda como 4 veces más que en mi mierda de portatil.... una burrada inexplicable... no se que puede estar pasando ...
alguna idea..?
Gracias
Responder Con Cita
  #10  
Antiguo 15-04-2008
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
¿Intentaste lo del modo virtual? Aquí tengo un par de ejemplos de ListView para mostrar archivos de una carpeta. Uno en modo normal y el otro en modo virtual. Pruébalos abriendo una carpeta con muchos archivos como c:\windows\system32 y ve la diferencia.

// Saludos
Responder Con Cita
  #11  
Antiguo 15-04-2008
Avatar de MaMu
MaMu MaMu is offline
Miembro
 
Registrado: abr 2006
Ubicación: Argentina
Posts: 863
Poder: 18
MaMu Va por buen camino
Cita:
Empezado por roman Ver Mensaje
¿Intentaste lo del modo virtual? Aquí tengo un par de ejemplos de ListView para mostrar archivos de una carpeta. Uno en modo normal y el otro en modo virtual. Pruébalos abriendo una carpeta con muchos archivos como c:\windows\system32 y ve la diferencia.

// Saludos
roman, hay forma de generar una vista de thubnails como el explorador de windows, en estos dos metodos de agregado de items del ListView?

Saludos
__________________
Código Delphi [-]
 
try 
ProgramarMicro(80C52,'Intel',MnHex,True);
except
On Exception do
MicroChip.IsPresent(True);
end;
Responder Con Cita
  #12  
Antiguo 16-04-2008
Avatar de lag_0
lag_0 lag_0 is offline
Miembro
 
Registrado: jul 2006
Posts: 131
Poder: 18
lag_0 Va por buen camino
Cita:
Empezado por MaMu Ver Mensaje
roman, hay forma de generar una vista de thubnails como el explorador de windows, en estos dos metodos de agregado de items del ListView?

Saludos
Claro, solo has de manejar la imagen que pinta, apartir de ese codigo (muy bueno por cierto) no es demasiado complicado, o siempre puedes dibujar en on draw item...
Responder Con Cita
  #13  
Antiguo 16-04-2008
Avatar de lag_0
lag_0 lag_0 is offline
Miembro
 
Registrado: jul 2006
Posts: 131
Poder: 18
lag_0 Va por buen camino
Me acabo de dar cuenta que el problema está en las comparaciones....
Uf... esto es lo peor... Solo son cadenas de texto qeu se comparan, además 4 cadenas con otras 4 por cada item que añado y tarda..... UF COMO TARDA!!! no entiendo qeu peude estar pasando, incluso dejando un simple if de las length se demora el additem un segundo por cada item... lo cual no es normal T________T....

Tiene alguna explicación? Pego el codigo...

Código Delphi [-]
function TfP.TraduceSMtoDB(Tipo:string;TextoA:string;TextoB:string):bool;
var
 TempI : integer;
 UCAa, UCAb:string;
begin
  TextoA := UpperCase(TextoA);
  TextoB := UpperCase(TextoB);
  Result := False;
  if ReplaceText(TextoA,' ','_') = ReplaceText(TextoB,' ','_') then begin
    Result := True;
    Exit;
  end;
  for TempI := 0 to ruleslist.Items.Count-1 do begin
     UCAa := UpperCase(ruleslist.Items.Item[TempI].SubItems.Strings[0]);
     UCAb := UpperCase(ruleslist.Items.Item[TempI].SubItems.Strings[1]);
     if ((TextoA = UCAa) or (TextoA = UCAb)) and ((TextoB = UCAa) or (TextoB = UCAb)) then begin
       if ((Tipo = 'n') and (ruleslist.Items.Item[TempI].Caption = 'Nombre')) or ((Tipo = 'i') and (ruleslist.Items.Item[TempI].Caption = 'IP')) or ((Tipo = 'd') and (ruleslist.Items.Item[TempI].Caption = 'Display Name')) or ((Tipo = 'm') and (ruleslist.Items.Item[TempI].Caption = 'Modelo')) then begin
         Result := true;
         Exit;
       end;
     end;
  end;
end;

Alguna idea? T_T muchas gracias...

Última edición por lag_0 fecha: 16-04-2008 a las 18:05:13.
Responder Con Cita
  #14  
Antiguo 17-04-2008
Avatar de MaMu
MaMu MaMu is offline
Miembro
 
Registrado: abr 2006
Ubicación: Argentina
Posts: 863
Poder: 18
MaMu Va por buen camino
Cita:
Empezado por lag_0 Ver Mensaje
Claro, solo has de manejar la imagen que pinta, apartir de ese codigo (muy bueno por cierto) no es demasiado complicado, o siempre puedes dibujar en on draw item...
Lo que pasa es que con GetSystemImage lo que obtengo es el ícono asociado a la extensión del archivo:

Código Delphi [-]
procedure TMainForm.GetSystemImages;
const
 shgfiLarge = SHGFI_SYSICONINDEX or SHGFI_LARGEICON;
  shgfiSmall = SHGFI_SYSICONINDEX or SHGFI_SMALLICON;
var
 ShFileInfo: TShFileInfo;
 iLarge: Cardinal;
  iSmall: Cardinal;
begin
 iLarge := ShGetFileInfo('', 0, ShFileInfo, SizeOf(ShFileInfo), shgfiLarge);
  iSmall := ShGetFileInfo('', 0, ShFileInfo, SizeOf(ShFileInfo), shgfiSmall);
 ListView_SetImageList(lvwFiles.Handle, iLarge, LVSIL_NORMAL);
 ListView_SetImageList(lvwFiles.Handle, iSmall, LVSIL_SMALL);
end;

Modo Virtual (OwnerData:=True)

Ahora bien, según interpreto el código expuesto por roman, el dato importante para trabajar con el ListView es el Item.Index, es el principal, en base a la lista creada con los elementos (la cantidad la muestro con AllocBy)
en el evento OnData, cargo los nombres de cada elemento (Item.Caption).
Para dibujar un thumbnail de cada elemento tendría mi código en:

Código Delphi [-]
 
procedure TMainForm.lvwFilesDrawItem(Sender: TCustomListView;
  Item: TListItem; Rect: TRect; State: TOwnerDrawState);
begin
end;

Pero que pasa con la propiedad OwnerDraw?.
En el evento OnDrawItem tendría que:

1. Generar el thumbnail del elemento
2. Dibujar el thumbnail del elemento
3. OwnerDraw True

es correcto?

Como sería un ejemplo de generar un thumbnail de un elemento de la lista y agregarlo al ListView?

PD: me resulta muy interesante todo este tema ya que, me gustaria generar un componente derivado del TShellListView, por el solo hecho de añadirle la propiedad ViewStyle [vsThumbs] + [ vsIcon, vsList, vsReport, vsSmallIcon]
y poder visualizar como Thumbnails, estilo Explorardor de Windows

Saludos y gracias
__________________
Código Delphi [-]
 
try 
ProgramarMicro(80C52,'Intel',MnHex,True);
except
On Exception do
MicroChip.IsPresent(True);
end;

Última edición por MaMu fecha: 17-04-2008 a las 01:10:46.
Responder Con Cita
  #15  
Antiguo 18-04-2008
Avatar de lag_0
lag_0 lag_0 is offline
Miembro
 
Registrado: jul 2006
Posts: 131
Poder: 18
lag_0 Va por buen camino
Mi idea para eso:
-añade un timagelist....
-Cuando exploren un directorio haces una búsqueda de todos los JPG y bmp y demás cargando cada imagen en el objeto que has creado antes... asegurate de hacerlo por orden alfabetica y de vaciar el timagelist antes de cargar...
-Cargas el listview con los ficheros del directorio ordenas por orden alfabetica el listview.
-Te aseguras de que el imagelist esté asociado al listview...
-pones el image index el indice de cada elemento y como son alfabeticos encajarán... Si quieres que la propiedad con la que se vea no sea icons solo tendrás que pintar la imagen asociada al elemento por imageindex al tamaño que tu quieras y como quieras... no es muy dificil prueba primero cambiar el font, color de texto etc del elemento y verás como sabiendo hacer eso llegas a cualquier sitio.
y listo.
Responder Con Cita
  #16  
Antiguo 18-04-2008
Avatar de MaMu
MaMu MaMu is offline
Miembro
 
Registrado: abr 2006
Ubicación: Argentina
Posts: 863
Poder: 18
MaMu Va por buen camino
Cita:
Empezado por lag_0 Ver Mensaje
Mi idea para eso:
-añade un timagelist....
-Cuando exploren un directorio haces una búsqueda de todos los JPG y bmp y demás cargando cada imagen en el objeto que has creado antes... asegurate de hacerlo por orden alfabetica y de vaciar el timagelist antes de cargar...
-Cargas el listview con los ficheros del directorio ordenas por orden alfabetica el listview.
-Te aseguras de que el imagelist esté asociado al listview...
-pones el image index el indice de cada elemento y como son alfabeticos encajarán... Si quieres que la propiedad con la que se vea no sea icons solo tendrás que pintar la imagen asociada al elemento por imageindex al tamaño que tu quieras y como quieras... no es muy dificil prueba primero cambiar el font, color de texto etc del elemento y verás como sabiendo hacer eso llegas a cualquier sitio.
y listo.
buenísima explicación, me voy a poner a jugar con el Listview y ver que sale!!!.

Saludos
__________________
Código Delphi [-]
 
try 
ProgramarMicro(80C52,'Intel',MnHex,True);
except
On Exception do
MicroChip.IsPresent(True);
end;
Responder Con Cita
  #17  
Antiguo 29-07-2008
Avatar de MaMu
MaMu MaMu is offline
Miembro
 
Registrado: abr 2006
Ubicación: Argentina
Posts: 863
Poder: 18
MaMu Va por buen camino
La verdad es que no entiendo como pasarlo a modo virtual, ya que quiciera probarlo puesto a que quiero trabajaron con centenares de imagenes.

Con un Form, un Button, un ImageList, un ListView y un Image, les dejo mi codigo para visualizar como thumbnails las imagenes jpg contenidas en una carpeta.

Alguien me ayuda a como pasarlo a modo virtual??? quizas asi me de cuenta.
Les agradezco de antemano. Me baje los ejemplos, y aun asi no he conseguido pararlo a virtual, me resulto interesante el comentario de "KeyBoy"

Aqui les va mi codigo, a ver si me ayudan a modificarlo:

Código Delphi [-]
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, ImgList;
type
  TForm1 = class(TForm)
    ListView1: TListView;
    Button1: TButton;
    Image1: TImage;
    ImageList1: TImageList;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  lista: TStrings;
  
implementation
{$R *.dfm}
uses ActiveX, ShlObj, ComObj;
type
 IExtractImage = interface ['{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}']
   function GetLocation(pszPathBuffer: LPWSTR; cchMax: DWORD; 
var pdwPriority: DWORD; const prgSize: SIZE; dwRecClrDepth: DWORD; 
var pdwFlags: DWORD): HRESULT; stdcall;
  function Extract(var phBmpImage: HBITMAP): HRESULT; stdcall;
 end;
function GetThumbnail(lpPathName, lpFileName: PWideChar; Width, Height: Integer): TBitmap;
var
 Desktop, Folder: IShellFolder;
 ItemIDList: PItemIDList;
 Flags, Priority: Cardinal;
 ExtractImage: IExtractImage;
 Res: HRESULT;
 hBitmap: Windows.HBITMAP;
 Buffer: array[0..MAX_PATH-1] of WideChar;
 Size: TSize;
begin
 Result := nil;
 SHGetDesktopFolder(Desktop);
 if LongBool(Desktop.ParseDisplayName(0, nil, lpPathName, PDWORD(0)^, ItemIDList, PDWORD(0)^)) then Exit;
 Desktop.BindToObject(ItemIDList, nil, IShellFolder, Folder);
 CoTaskMemFree(ItemIDList);
 if LongBool(Folder.ParseDisplayName(0, nil, lpFileName, PDWORD(0)^, ItemIDList, PDWORD(0)^)) then Exit;
 Folder.GetUIObjectOf(0, 1, ItemIDList, IExtractImage, nil, ExtractImage);
 CoTaskMemFree(ItemIDList);
 if not Assigned(ExtractImage) then Exit; // TODO
 Size.cx := Width; Size.cy := Height; Priority := 0;
 Flags := $28{IEIFLAG_SCREEN+IEIFLAG_OFFLINE};
 Res := ExtractImage.GetLocation(Buffer, SizeOf(Buffer), Priority, Size, 24{pf32bit}, Flags);
 if (Res = NOERROR) or (Res = E_PENDING{IEIFLAG_ASYNC}) then
  begin
   if not LongBool(ExtractImage.Extract(hBitmap)) then
    begin
     Result := TBitmap.Create;
     Result.Handle := hBitmap;
    end;
  end;
end;

procedure BuscarArchivos(const directorio, mascara: string;
  atributos: Integer; var listado: TStrings);
  // Procedimiento anidado
  //
  procedure Buscar(const subdirectorio: string);
  var
    regBusqueda: TSearchRec;
  begin
    // Buscar en el directorio
    if FindFirst(subdirectorio + mascara,atributos,regBusqueda) = 0 then
    begin
      try
        repeat
          Application.ProcessMessages;
          if (regBusqueda.Attr and faDirectory = 0)
            or (regBusqueda.Name <> '.')
              and (regBusqueda.Name <> '..') then
                listado.Add(subdirectorio + regBusqueda.Name);
        until FindNext(regBusqueda) <> 0;
      except
        FindClose(regBusqueda);
      end;
      FindClose(regBusqueda);
    end;
    // Buscar en los subdirectorios
    if FindFirst(subdirectorio + '*', atributos
      or faDirectory, regBusqueda) = 0 then
    begin
      try
        repeat
          Application.ProcessMessages;
          if ((regBusqueda.Attr and faDirectory) <> 0)
            and (regBusqueda.Name <> '.')
              and (regBusqueda.Name <> '..') then
                Buscar(subdirectorio + regBusqueda.Name + '\');
        until FindNext(regBusqueda) <> 0;
      except
        FindClose(regBusqueda);
      end;
      FindClose(regBusqueda);
    end;
  end;
begin
  Buscar(IncludeTrailingPathDelimiter(directorio));
end;

procedure TForm1.Button1Click(Sender: TObject);
var AItem: TListItem;
    i,w:integer;
    directorio,archivo:array[0..255] of WideChar;
    a,d:string;
    ar,di:PWideChar;
begin
  ListView1.Clear;
  ImageList1.Clear;
  lista := TStringList.Create;
  lista.Clear;
  BuscarArchivos('C:\Documents and Settings\Admin\Mis documentos\Mis imágenes', '*.jpg', faAnyFile, lista);
  for w:=0 to Lista.Count-1 do
    begin
      a:=ExtractFileName(Lista.Strings[w]);
      ar:=StringToWideChar((a),archivo,255);
      d:=ExtractFilePath(Lista.Strings[w]);
      di:=StringToWideChar(d,directorio,255);
      try
        Image1.Picture.Assign(GetThumbnail(di,ar, 96, 96));
        ImageList1.Add(Image1.Picture.Bitmap,nil);
      except
        on E: Exception do
          begin
            ShowMessage('Error: '+E.Message);
            EXIT;
          end;
       end;
    end;
  ListView1.Items.BeginUpdate;
  for i:=0 to Lista.Count-1 do
    begin
      AItem := ListView1.Items.Add;
      AItem.Caption := ExtractFileName(Lista.Strings[i]);
      AItem.SubItems.Add(Lista.Strings[i]);
      AItem.ImageIndex:=i;
    end;
  ListView1.Items.EndUpdate;   
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Lista.Free;
end;
end.

Muchas Gracias y Saludos
__________________
Código Delphi [-]
 
try 
ProgramarMicro(80C52,'Intel',MnHex,True);
except
On Exception do
MicroChip.IsPresent(True);
end;

Última edición por MaMu fecha: 29-07-2008 a las 17:29:33.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Añadir elementos sin repetir MaMu Varios 12 21-10-2015 22:17:40
XML y sus elementos papulo Varios 5 01-03-2007 11:13:30
TListView calogero Varios 0 18-01-2007 18:16:45
Tlistview Yenifer Varios 1 18-08-2004 17:33:44
Problemas al añadir elementos a una Lista en una aplicación tipo consola judoboy Varios 2 09-06-2003 14:58:48


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


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
Copyright 1996-2007 Club Delphi