AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Funktion ob Dateityp änderbares Symbol hat?

Funktion ob Dateityp änderbares Symbol hat?

Ein Thema von Popov · begonnen am 16. Mär 2014 · letzter Beitrag vom 17. Mär 2014
Antwort Antwort
Popov
(Gast)

n/a Beiträge
 
#1

Funktion ob Dateityp änderbares Symbol hat?

  Alt 16. Mär 2014, 18:26
Ich hab vorhin ein altes Programm ausgepackt, das einen kleinen Dateimanager beinhaltet. Dabei ist mir aufgefallen, dass ich mir zu jeder Datei den Icon hole und ihn in einer ImageBox speichere. Passend dazu wird der Index des Icons dem Item zugewiesen, usw.

Soweit funktioniert alles relativ gut (ist ja schon ein älteres Programm). Was mich aber nun stört, das ist die unnötige Speicherverschwendung. Habe ich 100 Jpeg Dateien im Ordner, speichere ich 100 mal das gleich Jpeg-Icon ab. Da muß nicht sein, da muss eine Icon-Verwaltung her.

Meine Frage ist nun, gibt es eine Funktion die mir sagt ob ein Dateityp ein stets gleiches oder ein änderbares Symbol hat? Jpeg, Bmp, Txp usw. kann ich kein anderes Symbol zuweisen. Exe auch nicht, aber jedes Programm hat ein anderes Symbol. Einer Verknüpfung kann ich ein anderes Symbol zuweisen, aber auch einem Ordner.

Meine erste Idee war in der Registry nachzugucken, aber das würde die Verhältnismäßigkeit sprengen. Eine andere Idee ist von jedem Icon ein Hashwert erstellen und die vergleichen. Optimal wäre es wenn das System einen darüber informieren würde ob es nötig ist.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
40.477 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Funktion ob Dateityp änderbares Symbol hat?

  Alt 16. Mär 2014, 18:44
Oder mach es dir einfach, denn auch unterschiedliche Typen können das selbe Icon besitzen.

Vor dem Hinzufügen des neuen Icons wird geprüft, ob schon ein "gleiches" in der Liste steht und wenn ja, dann wird das verwendet.

Gleich = z.B. die Pixel vergleichen (man könnte auch einen Hash der Farbwerte berechnen und den verwenden, um schneller zu verlgeichen/suchen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
8.485 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Funktion ob Dateityp änderbares Symbol hat?

  Alt 16. Mär 2014, 18:45
Dafür kannst du z.B. über SHGetFileInfo mit SHGFI_ICON das Icon abfragen:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#4

AW: Funktion ob Dateityp änderbares Symbol hat?

  Alt 17. Mär 2014, 06:39
Dafür kannst du z.B. über SHGetFileInfo mit SHGFI_ICON das Icon abfragen:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
SHGetFileInfo kenne ich, auch wenn ich es nicht sonderlich gut kenne. Ich weiß zwar nicht ganz genau was du meinst, aber iIcon liefert eine Indexnummer, die nur ein mal pro Symbol vorkommt. Im Grunde würde das reichen, denn daran kann man ein Icon erkennen, wenn du das meintest.

Trotzdem, so 100% weiß icch nicht was die Nummer zu bedeuten hat.

Zumindest habe ich ein Testcode geschrieben der nun mit 160 Symbolen auskommt, statt mit über 2700 im Windows\Sytem32 Ordner.

Was ich aber plötzlich habe, das ist eine EOutOfResources Meldung. Und das kommt etwas hier, wenn ich das Verzeichniss zum dritten Mal aufrufe:
Delphi-Quellcode:
  ImageList.Clear;
  Icon := TIcon.Create;
  try
    Icon.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Icon_1.ico');
    ImageList.AddIcon(Icon)
  finally
    Icon.Free;
  end;
Ist zwar nur Testcode, aber trotzdem. Bei AddIcon kommt irgendwann die Meldung. Das Icon Icon_1.ico ist nur ein Patzhalter, d. h. die Dateien bekommen zuerst dieses Symbol zugeweisen, damit sie sich die Liste schnell aufbauen kann, und erst im zweiten Durchgang wird das Icon wirklich gelesen.

Ich kann mir das sparen (alles ab der zweiten Zeile), dann bekomme ich zwar keine Fehlermeldung, aber SHGetFileInfo liefert dann irgendwann keine Icons mehr.
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#5

AW: Funktion ob Dateityp änderbares Symbol hat?

  Alt 17. Mär 2014, 08:06
...wenn ich das Verzeichniss zum dritten Mal aufrufe:
Delphi-Quellcode:
  ImageList.Clear;
  Icon := TIcon.Create;
  try
    Icon.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Icon_1.ico');
    ImageList.AddIcon(Icon)
  finally
    Icon.Free;
  end;
Was ist eigentlich in der ImageList, wenn Du ständig 'Icon.Free' aufrufst?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
8.485 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Funktion ob Dateityp änderbares Symbol hat?

  Alt 17. Mär 2014, 08:56
SHGetFileInfo kenne ich, auch wenn ich es nicht sonderlich gut kenne. Ich weiß zwar nicht ganz genau was du meinst, aber iIcon liefert eine Indexnummer, die nur ein mal pro Symbol vorkommt.
Auch, aber vor allem auch SHGFI_ICONLOCATION und dann szDisplayName in der Info-Struktur. Da steht ja der Dateiname der Datei drin, in der das Icon liegt, und in iIcon der Index innerhalb der Datei.
Nun brauchst du nur noch ein Dictionary (in Delphi 7 wohl am sinnvollsten eine TStringList oder THashedStringList) um diese Dateinamen auf die schon geladenen Icons zu mappen.

Was ist eigentlich in der ImageList, wenn Du ständig 'Icon.Free' aufrufst?
Das Icon. Siehe Doku:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
Zitat:
Because the system does not save hicon, you can destroy it after the function returns
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#7

AW: Funktion ob Dateityp änderbares Symbol hat?

  Alt 17. Mär 2014, 09:10
@ Furtbichler

Gute Frage. Ich ging bisher davon aus, dass eine Kopie erstellt wird, denn in der OH steht nichts von Übergabe oder Freigabe. Und es funktioniert so wie es ist, bzw. das geladene Icon ist nach der Freigabe immer noch in der ImageListe und wird fröhlich genutzt.

Auf der anderen Seite - Andersherum wird evtl. ein Schuh daraus (ich weiß es aber noch nicht). Wie ich schon sagte wird alles in zwei Schritten gemacht. Zuerst wird ein Platzhalter-Icon zugewiesen, damit der Aufbau schnell geht, im zweiten Durchgang wird dann das richtige Icon ermittelt, bzw. JustInTime. Jedes Mal wird vorher die ImageListe mit Clear leer gemacht.

In der Funktion für den zweiten Durchgang habe ich die Icons nach AddIcon anscheinend nicht freigegeben. Das macht 2700 x 2, also etwa 5400 Icons.

Nun habe ich es anders gemacht und gebe das Icon nach AddIcon frei. Bisherige keine Fehlermeldung.
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#8

AW: Funktion ob Dateityp änderbares Symbol hat?

  Alt 17. Mär 2014, 12:10
Obwohl jetzt keine Fehlermeldung kommt, ganz glücklich bin ich dann doch nicht, denn da scheint immer noch der Wurm drin zu liegen. Mal ein kleines Beispiel. Diesen Code kriege ich keine zwei mal ausgeführt, nur sehe ich keinen Fehler drin. Zwar ist das kein Code aus meinem vorherigen Problem, denn ich nutze nicht alle Icons, aber trotzdem. Wieso ist danach das Programm ausgelastet?
Delphi-Quellcode:
uses
  ShellApi;

procedure TForm1.Button1Click(Sender: TObject);
var
  SearchPath, FilePath: String;
  sr: TSearchRec;
  sfi: TSHFileInfo;
  Icon: TIcon;
begin
  SearchPath := 'c:\windows\system32\';

  if FindFirst(SearchPath + '*.*', faAnyFile or faDirectory, sr) = 0 then
  try
    repeat
      FilePath := SearchPath + sr.Name;

      if SHGetFileInfo(PChar(FilePath), 0, sfi, SizeOf(sfi), SHGFI_ICON or SHGFI_SMALLICON) <> 0 then
      begin
        Icon := TIcon.Create;
        try
          Icon.Handle := sfi.hIcon; //<<< hinzugefügt
          ImageList1.AddIcon(Icon);
        finally
          Icon.Free;
        end;
      end;
    until FindNext(sr) <> 0;
  finally
    FindClose(sr);
  end;

  ImageList1.Clear;

  ShowMessage('Laden fertig, und schon wieder gelöscht.');
end;
Was mir auffällt ist der Teil SHGetFileInfo(...) <> 0 . Zwar steht das nicht in der MSDN, denn da steht, dass bei Nichtnutzung von SHGFI_EXETYPE oder SHGFI_SYSICONINDEX der Erfolgsfall mit ungleich Null angezeigt wird, laut einer anderen Quelle gilt das auch für SHGFI_ICON und SHGFI_SMALLICON, womit hier ein Fehler vorliegen würde, aber selbst wenn, das dürfte nicht das Problem sein.

//EDIT

Scheint jetzt zu klappen. Anscheinend habe ich vorhin eine Zeile vergessen. Trotzdem, wieso der Unterschied? Mit der Zeile, alles ok, ohne Auslastung.

Geändert von Popov (17. Mär 2014 um 12:44 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf