Windows system icons

NickNameX
Beiträge: 19
Registriert: Di 22. Jun 2010, 13:52

Re: Windows system icons

Beitrag von NickNameX »

MAC hat geschrieben:ImageList1.Add(V_Image.Picture.Bitmap,nil);

Schön, aber ...

Die von WINDOWS im System benutzten Icons sollen geladen werden
(deren "Icon-Imagelisten-Handle" man über SHGetFileInfo() erhält)

Und das klappt nicht.


Genauer:
Ich erstelle (wie in einem der Beispiele) ein temporäres TIcon ( Icon := TIcon.Create; )
und weise diesem das FileInfo.Handle zu.

Das klappt bei den ersten beiden Files / Verzeichniseinträgen noch.
Bei (z.B.) dem Icon eines JPG-File ergibt

Icon.Handle:= FileInfo.Handle;

=> eine ACCESS VIOLATION

Sprich: Lazarus "verschluckt sich" am Icon.
Derselbe Code funktioniert einwandfrei unter Delphi 6.

Mag sein, daß ich über den von Dir genannten Umweg ein Icon
als Bitmap in eine ImageList hinein bekomme - aber ich
bekomme das Icon ja nichtmal ausgelesen !
Da kann ich auch nix mehr speichern ... :-(

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Windows system icons

Beitrag von MAC »

Es gibt eine möglichkeit mit handels, die ist aber doooooof, weil das image nach dem 2ten laden gelöscht wird, zumindest ein teil davon. Deshalb bedine ich mich hier eines , sehr, sehr schmutzigen tricks...
Aber funktioniert , mit ziemlich viel. Ausnahme Papierkorb (drag, drop) und Paragon Partition Manager™ 11 Free Edition.
Übrigens wusste ich nicht in welcher unit das Getfileicon war....

Das pogram läd das bild in ein image, und in eine imagelist. Es gib nur nen paar transparentsfehler von icon zu bitmap. Die haben mich jetzt aber nicht gestört xD

Wobei anzumerken ist das GetShellIcon von dieser Seite ist. http://www.delphipraxis.net/551825-post.html#641170
mein teil kannst du verwenden wofür du willst...
Dateianhänge
abc.zip
Beispielprogramm
(126.53 KiB) 112-mal heruntergeladen

Code: Alles auswählen

Signatur := nil;

NickNameX
Beiträge: 19
Registriert: Di 22. Jun 2010, 13:52

Re: Windows system icons

Beitrag von NickNameX »

Ich habe gerade nochmal sämtliche Links in diesem Artikel durchwühlt
und fand dann endlich deutliche Worte hier:
http://forum.lazarus.freepascal.org/ind ... pic=2140.0


=> The problem is that TIcon currently cannot cope with handles
(TIcon.setHandles is not yet implemented => TIcon.LoadFromBitmapHandles fails).


Die Lösung sieht ähnlich aus wie Deine.
Jetzt muß ich mal schauen ob dieses $80
in dem oben verlinkten Sourcecode
ohne ACCESS VIOLATION auch bei mir klappt ... ;-)

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Windows system icons

Beitrag von Socke »

NickNameX hat geschrieben:Ich habe gerade nochmal sämtliche Links in diesem Artikel durchwühlt
und fand dann endlich deutliche Worte hier:
http://forum.lazarus.freepascal.org/ind ... pic=2140.0


=> The problem is that TIcon currently cannot cope with handles
(TIcon.setHandles is not yet implemented => TIcon.LoadFromBitmapHandles fails).

Achtung: Diese Information könnte veraltet sein! In der Lazarus Roadmap wurde der Status von TIcon am 28. Oktober 2009 auf working gesetzt.
Wenn dem nicht so ist, ist das definitiv immer noch ein Bug.
Edit: Jahr der Änderung ergänzt
Zuletzt geändert von Socke am Mi 22. Dez 2010, 14:34, insgesamt 1-mal geändert.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Windows system icons

Beitrag von af0815 »

Socke hat geschrieben:....wurde der Status von TIcon am 28. Oktober auf working gesetzt.
Wenn dem nicht so ist, ist das definitiv immer noch ein Bug.

Oder man hat eine alte Lazarus Version :-) in Gebrauch.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Windows system icons

Beitrag von Socke »

af0815 hat geschrieben:Wenn dem nicht so ist, ist das definitiv immer noch ein Bug.

Oder man hat eine alte Lazarus Version :-) in Gebrauch.[/quote]Seit über einem Jahr nicht mehr upgedated? Respekt! :D
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

NickNameX
Beiträge: 19
Registriert: Di 22. Jun 2010, 13:52

Re: Windows system icons

Beitrag von NickNameX »

[quote="Socke"].. Diese Information könnte veraltet sein! In der Lazarus Roadmap wurde der Status von TIcon am 28. Oktober 2009 auf working gesetzt.
Wenn dem nicht so ist, ist das definitiv immer noch ein Bug.

Also, die Information hier ..
http://forum.lazarus.freepascal.org/ind ... pic=2140.0
stammt vom 10. August 2010.

Ich hab mal den neuesten LAZARUS Snapshot herunter geladen,
aber ich habe da im Moment wenig Hoffnung,
daß SETHANDLE bereits implementiert wurde .. (seh ich ja gleich ..)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Windows system icons

Beitrag von af0815 »

NickNameX hat geschrieben:Ich hab mal den neuesten LAZARUS Snapshot herunter geladen,

Vielleicht bei den persöhnlichen Einstellungen eintragen, welche Lazarusversion verwendet wird.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

NickNameX
Beiträge: 19
Registriert: Di 22. Jun 2010, 13:52

Re: Windows system icons

Beitrag von NickNameX »

af0815 hat geschrieben:
NickNameX hat geschrieben:Ich hab mal den neuesten LAZARUS Snapshot herunter geladen,

Vielleicht bei den persöhnlichen Einstellungen eintragen, welche Lazarusversion verwendet wird.

Beim hier vorliegenden UNIMPLEMENTED hätte das auch nicht geholfen .. :-(

Auch im aktuellen Snapshot ("von heute") ist es weiterhin nicht möglich,
die mit SHGetFileInfo ermittelte Icon-Liste im TreeView von Lazarus direkt zu verwenden.

TIcon.SetHandle ist weiterhin "unimplemented" (und nicht ein "Bug").

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Windows system icons

Beitrag von MAC »

man brauch es ja nicht direkt zu machen. Optimieren kann man , wenns klappt.
mein code (siehe oben) sollte eigentlich funktionieren , oder ?

Code: Alles auswählen

Signatur := nil;

NickNameX
Beiträge: 19
Registriert: Di 22. Jun 2010, 13:52

Re: Windows system icons

Beitrag von NickNameX »

Ja, Dein Code funktioniert.


Mein - (nur) unter Delphi funktionierender - Code macht folgendes:

-----------------------------------------

Code: Alles auswählen

{$IFDEF FPC}
//CreateImages for Lazarus :
...       SmallImagesList.Handle:= hImageList;    does not work
..        because Handle is ReadOnly  atm
{$ELSE}
//CreateImages for Delphi :
procedure TExplorerTreeView.CreateImages;   
  (holt sich das Handle auf die gesamte Liste)
  (nicht bloß ein einzelnes Icon ..)
var
  hImageList : Uint;
  SFInfo      : TSHFileInfo;
begin
  hImageList:= SHGetFileInfo( '', 0, SFInfo, SizeOf( SFInfo),
                                            SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
  if hImagesList <> 0 then
    begin
      SmallImagesList.Handle:= hImageList;
      SmallImagesList.ShareImages := True;
    end;
  Self.Images:= SmallImagesList;
end//CreateImages for Delphi
{$ENDIF}

-----------------------------------------


Ich müßte also - weil verschiedene Dinge unter Lazarus
nicht funktionieren - jedes Icon als Bitmap umwandeln
und manuell in meine eigene ImageListe einfügen.

Dann fehlt aber der Zusammenhang Icon <-> FileExtension.
Ich also kann GetIconIndex() mit SHGetFileInfo() nicht verwenden,
das die Position innerhalb der Windows-Imagelist ausliest.
Weil ich ja keinen Zugriff auf die gesamte Icon-Liste habe,
nur Zugriff auf einzelne, unsortierte Icons ..

Ein Workaround wäre möglich .. aber aufwändig :
- jedes gefundene und ausgelesene Icon (über BMP-Umweg) in die eigene Liste einfügen
- eine eigene Indexliste führen, also welcher Icon-Index in Windows
welchem Icon-Index in meiner eigenen Liste entspricht (Mapping)
- jedesmal prüfen ob Icon<->FileExtension vorhanden, wenn nicht, dann von Windows
in die eigene Image-Liste kopieren und die eigene Icon-Indexliste updaten


In der Summe:
Anstatt die Windows-Iconliste verwenden zu können
müßte ich eine Kopie anlegen und selber verwalten.

Das kann ja heiter werden ..

(siehe Bild, soweit isses ... )
Dateianhänge
Xplorer
Xplorer
Zuletzt geändert von Lori am Do 23. Dez 2010, 10:19, insgesamt 1-mal geändert.
Grund: Highlighter

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Windows system icons

Beitrag von Socke »

NickNameX hat geschrieben:TIcon.SetHandle ist weiterhin "unimplemented" (und nicht ein "Bug").

TIcon implementiert gar kein SetHandle(HBITMAP). Als Setter für die Handle-Eigenschaft wird SetIconHandle(HICON) eingeführt. Dieses typcastet dann das Handle auf ein THandle für TCustomIcon.SetHandle(THandle). Ich zitiere also von <lazarus-dir>/lcl/include/icon.inc:

Code: Alles auswählen

procedure TCustomIcon.SetHandle(AValue: THandle);
begin
  if FSharedImage.FHandle <> AValue
  then begin
    // if the handle is set externally we should unshare ourselves
    FreeCanvasContext;
    UnshareImage(false);
    FreeSaveStream;
    TSharedIcon(FSharedImage).Clear;
  end;
 
  if UpdateHandle(AValue)
  then begin
    if (TSharedIcon(FSharedImage).Count > 0) then
      FCurrent := 0
    else
      FCurrent := -1;
    Changed(Self);
  end;
end;

Was nicht implementiert ist, ist die Funktion TCustomIcon.SetHandles(HBITMAP, HBITMAP), die beide Handles -- für Icon und für die Maske -- setzt. TRasterImage.SetMaskHandle fällt auf die zuvor genannte Funktion zurück.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

NickNameX
Beiträge: 19
Registriert: Di 22. Jun 2010, 13:52

Re: Windows system icons

Beitrag von NickNameX »

Hallo Socke,

Danke daß Du das präzisiert hast. Die Foren-Beiträge nutze ich
auch immer gerne als "Wissens-Datenbank". Wer sich also
tiefer damit beschäftigen will, findet so schnell zum Kern des Problems.

Für TTreeView und TListView - und Verwendung von Icons - bleibt es derzeit leider dabei:
1) ImagesList.Handle:= hImageList; (Handle per SHGetFileInfo ermittelt) funktioniert nicht
2) ImageList.AddIcon auch nicht => aber der Umweg über Bitmap klappt ... :-(


Ich erweitere gerade eine TImageList mit zwei TStringLists
damit ich redundante Icons vermeiden kann:
(Edit: eigentlich müsste eine Stringlist reichen ..)

Die StringLists bekommen die mit SHGetFileInfo ermittelten
Bezeichnungen, über den ListenIndex der Stringlists
müste ich dann das passende Icon in meiner selbst befüllten Icon-Liste finden können.
So sollten dann am Ende TreeView und ListView so aussehen wie im Windows Explorer .. ;-)

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Windows system icons

Beitrag von MAC »

NickNameX hat geschrieben:Dann fehlt aber der Zusammenhang Icon <-> FileExtension.
Ich also kann GetIconIndex() mit SHGetFileInfo() nicht verwenden,
das die Position innerhalb der Windows-Imagelist ausliest.
Weil ich ja keinen Zugriff auf die gesamte Icon-Liste habe,
nur Zugriff auf einzelne, unsortierte Icons ..


jetzt versteh ich es, aber wieso meinst du das du kein zusammenhang hast. wenn du das icon von "hallo.exe" ausliest . dann hast du die file extension,

Code: Alles auswählen

copy('hallo.exe',length('hallo.exe')-4,3);

so ungefähr, vlt muss das -4 ein -3 sein ..

ich geb zu, es wär auf jeden fall aufwändiger als unter delphi, aber wenn das andere noch nicht implementiert ist...

Code: Alles auswählen

Signatur := nil;

NickNameX
Beiträge: 19
Registriert: Di 22. Jun 2010, 13:52

Re: Windows system icons

Beitrag von NickNameX »

MAC hat geschrieben:jetzt versteh ich es, aber wieso meinst du das du kein zusammenhang hast. wenn du das icon von "hallo.exe" ausliest . dann hast du die file extension,

Code: Alles auswählen

copy('hallo.exe',length('hallo.exe')-4,3);

so ungefähr, vlt muss das -4 ein -3 sein ..

ich geb zu, es wär auf jeden fall aufwändiger als unter delphi, aber wenn das andere noch nicht implementiert ist...


Es wäre ja Unsinn, das Icon mehr als einmal von der
Windows-Liste auszulesen. Also muß ich irgendwie
diese File-Extension (oder im Fall eines Ordners "Dateiordner",
im Falle eines Laufwerks das Wort "Laufwerk" etc ...)
zusammen mit dem Icon selber, geordnet in einer Liste, speichern.

Wo würdest Du denn das Sortier-Kriterum speichern ?
Damit ich in meiner eigenen ImageListe das richtige Icon auch wiederfinde ?

Sowas wie GetIconIndex() über SHGetFileInfo() geht ja nicht.
Der Icon-Index in der Windows-Systemliste ist
ein anderer als mein Index in der ImageList,
die ich selber mit Icons befüllt habe.


Gruß,
Peter

Antworten