Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Ikonice i TListView

[es] :: Pascal / Delphi / Kylix :: Ikonice i TListView

[ Pregleda: 2423 | Odgovora: 11 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Voodoo
Novi Beograd

Član broj: 3508
Poruke: 488
*.etf.bg.ac.yu.



+1 Profil

icon Ikonice i TListView08.12.2004. u 12:18 - pre 235 meseci
Razvijam jedan Total Commander klon i sasvim fino ide, osim jedne stvari: kako najefikasnije izvesti prikazivanje slicica levo od imena fajlova (lista je TListView namestena na Report stil)? Ako napravim TImageList i gradim listu ikonica svaki put kada ucitam direktorijum, iole veci broj fajlova se sto godina ucitava. Pokusao sam da izvedem to kao OwnerDraw, gde slicice extrakujem i prikazem samo kada se iscrtavaju (kao sto radi totalcmd) i to radi brzo, ali mi trulo izgleda (i plus sto ne znam da izvedem da preduga imena prikazem kao "Mnogodugoime...", sa tri tacke u nastavku a da izgleda lepo)...
Postoji li elegantno a efektivno resenje, kao sto radi Windows Explorer (posto on koristi ListView)? Istina, postoji sample koji koristi ListView kontrolu za prikazivanje fajlova kao explorer, ali ne zelim da se oslanjam na shell...
Zahvaljujem na svakom savetu.
 
Odgovor na temu

sasas
Saša Slavnić
radim za neke švabe

Član broj: 35478
Poruke: 617
*.zaslon-telecom.si.



Profil

icon Re: Ikonice i TListView08.12.2004. u 12:36 - pre 235 meseci
Ajde posalji kood, da pogledamo kako ti izgleda to kreiranje image list-a. Pomoglo bi da nam makar opises algoritam.
Tesko je ovako naslepo nagadjati sta si vec optimizovao a sta nisi...

ss.
When something is hard to do, then it's not worth doing.
 
Odgovor na temu

Riste Pejov
Team Leader/Senior Software Developer @
Ein-Sof ltd Skopje
Skopje, Macedonia

Član broj: 128
Poruke: 571
217.16.77.*

Jabber: richie@bagra.net.mk
ICQ: 154236769
Sajt: riste.softver.org.mk


Profil

icon Re: Ikonice i TListView08.12.2004. u 12:40 - pre 235 meseci
A zasto jednostavno ne presmetas prema velicini u pixelima koliko to predmeta moze da stane u vidljivoj povrsini i onda samo toliko dodas u ListView, i kada korisnik skroluje onda dodas ostatak, ili mozda dodas u tvojot aplikaciji backgroud thread koji ce puniti ListView iza vidljive povrsine.

Primer ako je recimo vidljiva povrsina listview-a 500 pixela, a visina jednog item-a u listview-u 25 pixela onda ucitas 200 njih a ostatak prepustis background thread-u da ucita.

Ili mozda i bi mogao da tekstove u realnom vremenu prikazes a ikonice ostavis background thread-u, sto mislim da bi bilo jos efektivnije resenje.

btw, a zasto gradis listu ikonica svaki put kad ucitas dir ?
People who think they know everything tend to irritate those of us who do.
 
Odgovor na temu

Voodoo
Novi Beograd

Član broj: 3508
Poruke: 488
*.etf.bg.ac.yu.



+1 Profil

icon Re: Ikonice i TListView08.12.2004. u 12:53 - pre 235 meseci
Zato sto TListItemu moze da se dodeli samo ikonica koja je u TImageListu dodeljenom roditeljskoj TListView kontroli...

algoritam za ucitavanje je standardan (nemam src ovde pa je ovo iz glave):

found := FindFirst(...)
while found = 0 do
begin
if sr.name <> '.' then
item := LevaLista.items.add;
item.caption := sr.name;
...
findnext(sr);
end;
findclose(sr);

E sad, ako gradim TImageListu, onda iscupam ikonu sa ExtractAsociatedIcon, dodam je u listu i stavim item.imageindex := brojac koji se povecava...
samo ovo traje podosta (recimo /windows/system32 se dosta dugo puni... komp je P3, ali hocu da radi na svakom krshu)...

Mada to nije losa ideja, da buildujem TImageListu samo za iteme koji se trenutno vide...
 
Odgovor na temu

sasas
Saša Slavnić
radim za neke švabe

Član broj: 35478
Poruke: 617
*.zaslon-telecom.si.



Profil

icon Re: Ikonice i TListView08.12.2004. u 13:03 - pre 235 meseci
Veliku ustedu ces postici 'kesiranjem' ikonica. Recimo, ikona za word, mp3, .dll je uvek ista i nema potrebe da je za svaki fajl extractujes.
Prilikom pokretanja programa pronadji sve registrovane ekstenzije i ucitaj njihove ikone u image listu. Tako ti ostaje da kad citas dir. samo dodajes ikonice za .exe fajlove.
ExtractIcon je vremenski skupa operacija, a ovim ces izbeci njeno stalno ponavljanje.

ss.
When something is hard to do, then it's not worth doing.
 
Odgovor na temu

Riste Pejov
Team Leader/Senior Software Developer @
Ein-Sof ltd Skopje
Skopje, Macedonia

Član broj: 128
Poruke: 571
217.16.77.*

Jabber: richie@bagra.net.mk
ICQ: 154236769
Sajt: riste.softver.org.mk


Profil

icon Re: Ikonice i TListView08.12.2004. u 14:51 - pre 235 meseci
A zasto ne napises novu klasu, koja ce imati objekte TImageList i TStringList i svaki put kad naletis na tip fajla (extenzija) koju vec nemas u ListView, onda pozoves neki public method (pr GetImageIndex) u kome predas extenziju fajla, i onda samo uz AStringList->IndexOf(ext) dobijes index icone iz ImageList-a. I dodas iconindex u listview. Ukoliko ti extenzija ne postoji, onda lepo uradis ExtractIcon i dodas ikonu u tvojoj ImageList-i sa extenzijom u StringList-u. Na kraj izvrsenja programa mozes stream-ovati ikone na tvrdi disk i na pocetka rada programa ih opet ucitati .... :)

A ako zelise da ovo radi maksimalno brzo, samo odaberi najcesce koriscene ikone i napuni imagelist sa jedno 50-tak ikonica i to ti je to, sve drugo sto nemas u listi, onda lepo ili postavis onu standardnu ikonicu sa prozorcicem iz windowsa ili uradi ExtractIcon
People who think they know everything tend to irritate those of us who do.
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
195.252.80.*

ICQ: 246436949


+10 Profil

icon Re: Ikonice i TListView08.12.2004. u 14:59 - pre 235 meseci
Mozda bi mogao da napises neki svoj Icon Resource Manager? Mozda ovo zvuci malo komplikovano, ali mozda bi ipak moglo da radi ovako:

Napravis klasu koja cuva ikonicu i neki tag (recimo ekstenziju ili puno ime fajla) po kojoj mozes da izvadis odredjenu ikonicu. Znaci... krenes da citas iz Reg., procitas ikonicu za *.mp3 i ubacis je u manager sa tagom "*.mp3", zatim za *.doc... itd. Kasnije kad hoces da pronadjes ikonicu samo pozoves npr. funkciju GetIcon('Pesma.mp3') i manager prvo potrazi da li ima neka ikonica sa tagom "Pesma.mp3" ako je nema onda potrazi sa tagom "*.mp3" ako ni toga nema iscrta ti neku default ikonicu.
Prilikom pokretanja programa iscitas sve standardne ikonice iz Reg. (bice taman dosta vremena da se vidi tvoj splash screen ;) ) i kasnije kad god imas neki .exe, .pif ili .lnk fajl proveris samo da li imas ikonicu u manageru. Ako je nemas ucitas je i pici ;) Jedino sto bi bilo lepo je da pazis da ne zauzmes previse memorije. Ogranicis listu na odredjen broj ikonica i kada treba da dodas novu, a lista ti je puna samo izbrises neku od ikonica .exe fajlova ili ako mozes da znas onu koja najduze nije citana iz managera.
 
Odgovor na temu

Voodoo
Novi Beograd

Član broj: 3508
Poruke: 488
*.etf.bg.ac.yu.



+1 Profil

icon Re: Ikonice i TListView08.12.2004. u 16:13 - pre 235 meseci
Zahvaljujem na savetima momci, probacu sve ovo cim dodjem kuci.
 
Odgovor na temu

bancika
Branislav Stojkovic

Član broj: 24844
Poruke: 631
213.244.197.*

Sajt: www.diy-fever.com


+1 Profil

icon Re: Ikonice i TListView08.12.2004. u 16:26 - pre 235 meseci
mozes preko API-ja da dobijes handle od sistemskog listView-a koji sadrzi sve ikonice (osim ikona koje predstavljaju ikone - znaci samo ikone za registrovane tipove), to brzo radi koliko znam. takodje koristis api funkcije da dobijes ImageIndex ikone za odredjeni fajl. Nemam bas pri sebi taj kod ali sam vidjao po netu. Ja imam neki ali ne radi bas najbolje na XP-u. Drugi nacin je (tako sam ja radio u jednom svom programu) da dinamicki pravis ListView tako sto svaki put kad otvoris neki direktorijum proveravas da li u listview do tad postoji ikonica za taj tip ili ne. ako nema onda preko API-ja uzmes ikonicu i ubacis je u listview.
Evo koda za to
Code:

function TMainForm.GetSmallIcon(Name: string): Integer;
var
  FileInfo: TSHFileInfo;
  aIcon: TIcon;
begin
  // clear the memory
  FillChar(FileInfo, SizeOf(FileInfo), #0);
  // get a handle to the ImageList for the file selected
  SHGetFileInfo(PChar(Name), 0, FileInfo, SizeOf(FileInfo),
                SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SHELLICONSIZE);

  aIcon := TIcon.Create;
  // assign the handle of the icon returned
  aIcon.Handle := FileInfo.hIcon;
  // lets paint it transparent
  aIcon.Transparent := True;
  if Name[Length(Name)] = '\' then //za folder
    ObjectIconsSmall.ReplaceIcon(0, aIcon)
  else
    Result := ObjectIconsSmall.AddIcon(aIcon); //za fajl
  // free our icon class
  FreeAndNil(aIcon);
  DestroyIcon(FileInfo.hIcon);
end;


analogno za vece ikone, koristi flag SHGFI_LARGEICON,, rezultat je ImageIndex dodate ikone

uzgred, mozda ne znas, ali na XP-u moras da konvertujes ImageList u 32bitni format da bi mogao da stavljas XP-ove fancy ikone sa alpha kanalom. To se radi ovako

Code:

procedure TMainForm.ConvertTo32BitImageList(const ImageList: TImageList);
const
  Mask: array[Boolean] of Longint = (0, ILC_MASK);
var
  TemporyImageList: TImageList;
begin
  if Assigned(ImageList) then
  begin
    TemporyImageList := TImageList.Create(nil);
    try
      TemporyImageList.Assign(ImageList);
      with ImageList do
      begin
        ImageList.Handle := ImageList_Create(Width, Height, ILC_COLOR32 or Mask[Masked], 0, AllocBy);
        if not ImageList.HandleAllocated then
        begin
          raise EInvalidOperation.Create(SInvalidImageList);
        end;
      end;
      ImageList.AddImages(TemporyImageList);
    finally
      TemporyImageList.Free;
    end;
  end;
end;


nadam se da ima vajde od ovoga :)
Ride the rainbow, crack the sky

DIY gitare, pojacala i efekti www.diy-fever.com
 
Odgovor na temu

Voodoo
Novi Beograd

Član broj: 3508
Poruke: 488
*.beograd-2.tehnicom.net.



+1 Profil

icon Re: Ikonice i TListView09.12.2004. u 10:02 - pre 234 meseci
Evo rezultata:
Napravio sam cache svih registrovanih ikona tako sto sam zaredjao po HKEY_CLASSES_ROOT, pokupio ekstenzije, onda otvorio ponaosob svaku i njen DefaultIcon potkljuc i izvadio EXE koji sadrzi ikonu. I to sad kako-tako radi (moram jos nesto da izvedem, izmedju ostalog i ono za ubacivanje alpha kanala u ikonu, ali to kasnije).

Da li bi neko hteo da pogleda ove funkcije koje sam pravio, da negde ne postoji memory leak (mozda nisam rucno unistio nesto sto je trebalo)? Hvala.

Code:
//-------------------------------------------------------------------------
// CUPANJE IMENA IZ "IME,INDEKS" STRINGA
//-------------------------------------------------------------------------
function GetExeName(S: string): string;
var
  kopija: string;
  i: Integer;
  res: string;
  winpath: array[0..259] of char;
begin
  if AnsiContainsStr(S, '%SystemRoot%') then
  begin
    FillChar(winpath, 260, #0);
    GetWindowsDirectory(winpath, 259);
    kopija := AnsiReplaceStr(S, '%SystemRoot%', StrPas(winpath));
  end
  else kopija := Copy(S, 1, Length(S));
  res := '';
  for i := 1 to Length(kopija) do
  begin
    if kopija[i] = '"' then Continue;
    if kopija[i] = ',' then Break;
    res := res + kopija[i];
  end;
  Result := res;
end;
//-------------------------------------------------------------------------
// CUPANJE INDEKSA IZ "IME,INDEKS" STRINGA
//-------------------------------------------------------------------------
function GetIconIndex(S: string): Integer;
var
  i: Integer;
  sgn: Integer;
  res: Integer;
  SreliSmoZarez: Boolean;
begin
  SreliSmoZarez := False;
  res := 0;
  sgn := 1;
  for i := 1 to Length(S) do
  begin
    if S[i] = ',' then SreliSmoZarez := True;
    if (S[i] = '-') and (SreliSmoZarez) then sgn := -1;
    if (Ord(S[i]) >= Ord('0')) and (Ord(S[i]) <= Ord('9')) and (SreliSmoZarez) then res := (res * 10) + StrToInt(S[i]);
  end;
  Result := sgn * res;
end;
//-------------------------------------------------------------------------
// KESIRANJE SVIH REGISTROVANIH IKONA
//-------------------------------------------------------------------------
procedure CacheRegIcons(ExtList: TStringList; ImgList: TImageList);
var
  Reg: TRegistry;
  StrList: TStringList;  // Pomocna lista za sve kljuceve iz HKEY_CLASSES_ROOT
  i: Integer;
  RegTip: string;
  RegExe: string;
  Icon: TIcon;
  SmIcon: HICON;
  LgIcon: HICON;
begin
  ExtList.Clear;
  StrList := TStringList.Create;
  Reg := TRegistry.Create(KEY_READ);
  Reg.RootKey := HKEY_CLASSES_ROOT;
  Reg.OpenKey('', False);
  Reg.GetKeyNames(StrList);
  Reg.CloseKey;
  // Vadjenje samo onih kljuceva koji su ekstenzije
  for i := 0 to (StrList.Count - 1) do
    if StrList.Strings[i][1] = '.' then ExtList.Add(LowerCase(StrList.Strings[i]));
  StrList.Free;
  // Cupanje ikona za svaku ekstenziju
  for i := 0 to (ExtList.Count - 1) do
  begin
    Reg.OpenKey(ExtList.Strings[i], False);
    RegTip := Reg.ReadString('');
    Reg.CloseKey;
    Reg.OpenKey(RegTip + '\DefaultIcon', False);
    RegExe := Reg.ReadString('');
    Reg.CloseKey;
    Icon := TIcon.Create;
    if not FileExists(GetExeName(RegExe)) then ImgList.GetIcon(1, Icon) else
    begin
      ExtractIconEx(pchar(GetExeName(RegExe)), GetIconIndex(RegExe), LgIcon, Smicon, 1);
      Icon.Handle := SmIcon;
    end;
    ImgList.AddIcon(Icon);
  end;
  Reg.Free;
end;
 
Odgovor na temu

Voodoo
Novi Beograd

Član broj: 3508
Poruke: 488
*.neobee.net.



+1 Profil

icon Re: Ikonice i TListView09.12.2004. u 10:33 - pre 234 meseci
Ubacio sam i ovo za 32-bit color ikone i radi... doduse tek kada sam dodao CommCtrl u 'uses' listu :)
(nisam ni znao do sada da su komon kontrole razdvojili u ComCtrls i CommCtrl)

Nego evo da pogledate na sta to lici... solidan broj ikona se ne prikazuje kako treba (to jest prikazuju se pogresne), ali bice ispravljeno.

http://www.geocities.com/ivantod84/VN01.zip
 
Odgovor na temu

Voodoo
Novi Beograd

Član broj: 3508
Poruke: 488
*.neobee.net.



+1 Profil

icon Re: Ikonice i TListView10.12.2004. u 11:04 - pre 234 meseci
Odradio sam i OwnerDrawn verziju, ako nekog interesuje moze skinuti sa istog linka...
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Ikonice i TListView

[ Pregleda: 2423 | Odgovora: 11 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.