Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Icon aus beliebiger Datei extrahieren (z.B. *.lnk) (https://www.delphipraxis.net/55412-icon-aus-beliebiger-datei-extrahieren-z-b-%2A-lnk.html)

Martin K 20. Okt 2005 15:34


Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
Hallo

wie kann man aus einer beliebigen Datei das dazugehörige Icon ermitteln?
Sollte nicht nur bei EXE-Dateien gehen, wie z.B. bei ExtractIconEx - sondern auch z.B. bei *.lnk Verknüpfungen.
Komme ich da mit SHGetFileInfo weiter?
Am besten wäre, ich bekomme das Icon der *.lnk als TBitmap geliefert.

Danke, schon im Voraus!

kingflo 20. Okt 2005 16:08

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
Also bei exe funzt dieser code bei anderen sachen hab ichs noch net getestet und kann ich hier leider auch nicht versuchs einfach...


Delphi-Quellcode:
function GetDefaultIcon(Filename: Widestring; IconTyp: Cardinal = 2): HIcon;
var
  Info: TSHFileInfoW;
  Flags: Cardinal;
  ext: WideString;
  idx: word;
begin
  //Result := Ticon.Create;
  ext := WideExtractFileExt(Filename);
  idx := 0;
  if WideFileExists(Filename) then
  begin
    result := Tnt_ExtractAssociatedIconW(HInstance, PWideChar(Filename), idx);
    exit;
  end;
  {if ext = '.ico' then
  begin
    result := LoadFromFile(Filename);
    exit;
  end;}

  begin {DW 1.4}
    Flags := 0;
    case IconTyp of
      0: Flags := SHGFI_ICON or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES;
      1: Flags := SHGFI_ICON or SHGFI_LARGEICON or SHGFI_USEFILEATTRIBUTES;
      2: Flags := SHGFI_ICON or SHGFI_SHELLICONSIZE or SHGFI_USEFILEATTRIBUTES;
    end;
    Tnt_SHGetFileInfoW(PWideChar(ext), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), Flags);
    Result := Info.hIcon;
  end;
end;

{TntWiindows.pas}

function Tnt_ExtractAssociatedIconW(hInst: HINST; lpIconPath: PWideChar;
  var lpiIcon: Word): HICON;
begin
  if Win32PlatformIsUnicode then
    Result := ExtractAssociatedIconW{TNT-ALLOW ExtractAssociatedIconW}(hInst, lpIconPath, lpiIcon)
  else
    Result := ExtractAssociatedIconA{TNT-ALLOW ExtractAssociatedIconA}(hInst,
      PAnsiChar(AnsiString(lpIconPath)), lpiIcon)
end;

Martin K 20. Okt 2005 16:27

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
Danke schon mal für deinen Code,
aber da kommen bei mir versch. "Undeclared identifier", z.B. bei 'WideFileExists'.
Fehlt da ein Eintrag in uses ?

bei EXE-Dateien ist das nochmal was anderes, weil das Icon in der exe integriert ist.
Bei einer *.lnk Verknüpfung ist ja nur ein Verweis drin, der auf ein Icon zeigt (z.B. wenn man in Windows die Eigenschaften einer Verknüpfung aufruft und dann auf "Anderes Symbol" klickt, erhält man diesen Verweis auf das Icon).

Diesen Verweis einer *.lnk will ich jetzt mit Delphi auslesen,
und dann das Icon in ein TBitmap laden.

Der Verweis zeigt meißtens auf eine EXE-Datei, ICO-Datei oder DLL-Datei, die dann das Icon enthalten.

Also müsste ich erst den Verweis auf das Icon auslesen,
und dann das Icon aus der EXE, ICO oder DLL extrahieren und in ein TBitmap laden.

Weiß da jemand eine Lösung?

ichbins 20. Okt 2005 16:50

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
Theoretisch müsste es so funken:
Delphi-Quellcode:
uses
  shellapi

[...]

function iconhandle(filename:string):hicon;
var
  psfi:_shfileinfoa;
  c1,c2,c3:cardinal;
begin
  shgetfileinfo(pansichar(filename),c1,psfi,c2,c3);
  result:=psfi.hicon;
end;

//Verwendung:

var
  i:ticon;
begin
  i:=ticon.Create;
  i.Handle:=iconhandle('c:\file.lnk');
mit der Praxis sieht es immer ein bisschen anders aus :wall:

als iconhandle gibt er immer 0 raus :?

Martin K 20. Okt 2005 17:06

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
Hab deinen Code mal getestet, das Programm läuft auch.

Hab das noch unten hinzugefügt:
Delphi-Quellcode:
  Image1.Picture.Icon:=i;
aber es wird einfach nix im Image1 angezeigt.

Dann kommen noch diese Meldungen:
Zitat:

[Warning] Unit1.pas(39): Variable 'c1' might not have been initialized
[Warning] Unit1.pas(39): Variable 'c2' might not have been initialized
[Warning] Unit1.pas(39): Variable 'c3' might not have been initialized
Aber daran kann's ja wohl nich liegen...

Irgend eine Idee ? :gruebel:

ichbins 20. Okt 2005 17:12

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
die Funktion will noch andere Werte zurückliefern, die aber uninterresant sind. ich muss aber variablen angeben, in die die Funktion sie speichern will. Also helf ich mir mit c1, c2 und c3 aus. Diese Variablen sind vollkommen unbedeutend.

Die Funktion liefert irgendwie immer das Icon-Handle 0 zurück... :?

psfi.hicon in der Funktion hat aber noch nen wert :gruebel:

oder doch nicht? gerade hat das showmessage eine Zahl ausgegeben. Das war aber, als ich eine nicht existierende Datei probiert hab.

Versuch mal im Forum zu suchen. Da gibt's bestimmt was.

Martin K 20. Okt 2005 17:18

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
Was sind denn für Daten in einem _shfileinfoa drin?
Und was ist das überhaupt?
(Also in diesem Fall das 'psfi')

ichbins 20. Okt 2005 17:23

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
das isn record.


die Funktion shgetfileinfo braucht eben das als Parameter. Es enthält meherere Informationen, die von der Funktion dann gesetzt werden. Gib mal innerhalb der iconhandle-funktion die Buchstabenfolge
Delphi-Quellcode:
psfi.
ein, dann müsste er dir alle enthaltenen Typen auflisten (Programmierhilfe)

Martin K 20. Okt 2005 17:34

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
Danke, das hab ich schon.
Meinst du, man sollte in psfi schon ein paar Werte reinschreiben, bevor
Delphi-Quellcode:
shgetfileinfo(pansichar(filename),1,psfi,1,1);
aufgerufen wird ?

Hab das im Forum gefunden:
Delphi-Quellcode:
tmpImgLst.Handle := SHGetFileInfo(PChar(FName),0,FileInfo,sizeof(FileInfo),SHGFI_SYSICONINDEX or SHGFI_ICON);
tmpImgLst.GetBitmap(FileInfo.iIcon,tmpBitmap);
Meinst du, das hilft uns weiter?

ichbins 20. Okt 2005 17:34

Re: Icon aus beliebiger Datei extrahieren (z.B. *.lnk)
 
Jetzt hab ichs:
DP zu Fileicon

der Thread (ist das richtig geschrieben?) wirkt ziemlich selbstsicher.

Da heisst es so:

Delphi-Quellcode:
procedure TForm1.DrawFile(Name: String);
var
  FileInfo: TSHFileInfo;
  ImageListHandle: THandle;
  aIcon: TIcon;
begin
  // Speicher löschen
  FillChar(FileInfo, SizeOf(FileInfo), #0);
  // Handle der Image Liste der ausgewählten Datei ermitteln
  ImageListHandle := SHGetFileInfo(
    PChar(Name), 0, FileInfo, SizeOf(FileInfo),
    // großes Icon verlangen
    SHGFI_ICON or SHGFI_LARGEICON
  );
  try
    // TIcon Objekt erstellen
    aIcon := TIcon.Create;
    try
      // Icon Handle zuweisen
      aIcon.Handle := FileInfo.hIcon;
      // Transparent darstellen
      aIcon.Transparent := True;
      with PaintBox1 do
      begin
         // Paintbox auf die entsprechende Größe bringen
         Width := aIcon.Width;
         Height := aIcon.Height;
         Application.ProcessMessages;
         // Paintbox löschen
         Canvas.Rectangle(-1, -1, Succ(Width), Succ(Height));
         // Icon darstellen
         Canvas.Draw(0, 0, aIcon);
      end;
    finally
      // TIcon Objekt freigeben
      FreeAndNil(aIcon);
    end;
  finally
    // Icon der Shell wieder freigeben
    DestroyIcon(FileInfo.hIcon);
    // Icon Liste der Shell wieder freigeben
    ImageList_Destroy(ImageListHandle);
  end;
end;
das geht
:bouncing4:
:cheers:


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:49 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz