// Getestet mit D4 unter XP

// In einem modernen Windows-Icon befinden sich oft mehrere Icons in den
// verschiedensten Größen. Wenn man so ein Icon in ein Image lädt, wird es
// aber mit seiner Standardgröße geladen
(meist 32x32). Mit dem folgenden
// Code kann man auch größere
(bzw. kleinere) Icons zur Laufzeit aus einer
// Datei in ein TImage laden. Wenn sich ein so genanntes XP-Icon in der
// vorgegebenen Größe in dieser Datei befindet, wird es bevorzugt geladen.
// Wenn nicht, dann lädt der Code ein einfaches Icon der entsprechenden Größe.
// Ist das auch nicht vorhanden, dann wird ein anderes Icon gestreckt
// dargestellt. Die Variable
Schatten legt bei einem XP-Icon die Farbe des
//
(alpha)Schattenrandes fest. Man kann sie auch auf die Hintergrundfarbe
// setzen, dann fällt der Schatten bei gleichfarbigem Untergrund nicht auf. Bei
// nicht-XP-Icons sollte die die Schattenfarbe nicht innerhalb des Iconsbildes
// vorkommen, da es sonst zu "Löchern" kommen kann, falls
Transparent=True ist.


// Variante 1: Ein Icon aus einer *.ico Datei laden

 
function LoadBigIco(const Datei: string; Image: TImage; 
  cx, cy: Integer; Schatten: TColor; Transparent: Boolean): Boolean; 
var 
  h: HIcon; 
  hb: HBrush; 
begin 
  Result := false; 
  Schatten := ColorToRGB(Schatten); 
  hb := CreateSolidBrush(Schatten); 
  h := LoadImage(0, pchar(Datei), IMAGE_ICON, cx, cy, LR_LOADFROMFILE); 
  if h <> 0 then begin 
    Image.Autosize := true; 
    Image.Transparent := Transparent; 
    with Image.picture.bitmap do begin 
      TransparentColor := Schatten; 
      with canvas do begin 
        width := cx; 
        height := cy; 
        brush.color := Schatten; 
        Fillrect(Cliprect); 
        DrawIconEx(handle, 0, 0, h, cx, cy, 0, hb, DI_NORMAL); 
      end; 
    end; 
    DeleteObject(hb); 
    DestroyIcon(h); 
    Result := true; 
  end; 
end; 


// Beispielaufruf

procedure TForm1.Button3Click(Sender: TObject); 
begin 
  if not 
    LoadBigIco('D:\Icons\test.ico', Image2, 48, 48, clBtnFace, true) 
    then showmessage('Icon nicht gefunden!'); 
end;


//----------------------------------------------------------------------------


// Variante 2: Ein Icon aus *.dll, *.ocx, *.tsp, *.rll, *.exe Datei laden. Dabei
               beginnt die Zählung der Icons bei Eins. Das bedeutet, dass man
               mit
idx=29 auch das 29. Icon aus der Datei holt (falls überhaupt
               soviel drin sind)
. Ansonsten muss man die Namen der Icons kennen
               oder ermitteln und die Icons darüber aufrufen. Falls Icons mit
               16 Farben und gleichgroße mit mehr als 16 Farben vorhanden sind,
               kann man mit der Variablen "Art" vom Typ "anzeige" auswählen,
               welche man sehen will
.
 

type 
  anzeige = (lrDefault, lrVGA); 
 
function LBIFL(lib: THandle; idx: pchar; Image: TImage; Art: anzeige; 
  cx, cy: Integer; Schatten: TColor; Transparent: Boolean): Boolean; 
var 
  h: HIcon; 
  hb: HBrush; 
begin 
  Result := false; 
  Schatten := colortorgb(Schatten); 
  hb := createsolidbrush(Schatten); 
  h := loadimage(lib, idx, IMAGE_ICON, cx, cy, ord(Art) * 128); 
  if h <> 0 then begin 
    Image.Autosize := true; 
    Image.Transparent := Transparent; 
    with Image.picture.bitmap do begin 
      TransparentColor := Schatten; 
      with canvas do begin 
        width := cx; 
        height := cy; 
        brush.color := Schatten; 
        fillrect(cliprect); 
        drawiconex(handle, 0, 0, h, cx, cy, 0, hb, DI_NORMAL); 
      end; 
    end; 
    deleteobject(hb); 
    destroyicon(h); 
    Result := true; 
  end; 
end; 
 
function Proc(modul: THandle; rtype, rname: PChar; 
  Liste: TStrings): Integer; stdcall; 
begin 
  if HiWord(ULong(rname)) <> 0 then Liste.Add(rname) 
  else Liste.Add(Format('#%d', [Word(rname)])); 
  Result := 1; 
end; 
 
function LoadBigIcoFromLib(const Datei: string; idx: PChar; Image: TImage; 
  cx, cy: Integer; Schatten: TColor; Art: anzeige; Transparent: Boolean): Boolean; 
var 
  sl: Tstringlist; 
  lib: THandle; 
  id: Word; 
begin 
  result := false; 
  try 
    id := strtointdef(idx, maxword); 
  except 
    exit; 
  end; 
  sl := TStringlist.create; 
  lib := LoadLibraryEx(PChar(Datei), 0, LOAD_LIBRARY_AS_DATAFILE); 
  if lib <> 0 then begin 
    EnumResourceNames(lib, RT_GROUP_ICON, @Proc, Integer(sl)); 
    if (id > 0) and (id <= sl.count) or (id = maxword) then begin 
      if id < maxword then idx := pchar(sl[pred(id)]); 
      result := LBIFL(lib, idx, Image, Art, cx, cy, Schatten, Transparent); 
    end; 
    FreeLibrary(lib); 
  end; 
  sl.free; 
end; 
 
 
// Beispielaufruf mittels Index (Stellung des Icons innerhalb der Datei) 
 
procedure TForm1.Button3Click(Sender: TObject); 
var 
  idx: word; 
begin 
  idx := 60; 
  if not LoadBigIcoFromLib('c:\windows\system32\shell32.dll', 
    PChar(IntToStr(idx)), Image1, 48, 48, clBtnFace, lrVGA, false) 
    then showmessage('Icon konnte nicht geladen werden!'); 
end; 
 
 
// Zwei Beispielaufrufe mittels Name (bei Zahlen # vorangesetzt) 
 
procedure TForm1.Button4Click(Sender: TObject); 
begin 
if not LoadBigIcoFromLib('c:\windows\system32\shell32.dll', 
    PChar('#139'), Image1, 48, 48, clBtnFace, lrDefault, false) 
    then showmessage('Icon konnte nicht geladen werden!'); 
end; 
 
procedure TForm1.Button5Click(Sender: TObject); 
begin 
  if not LoadBigIcoFromLib('c:\windows\system32\hhctrl.ocx', 
    PChar('ICONCDROM'), Image1, 32, 32, clBtnFace, lrDefault, false) 
    then showmessage('Icon konnte nicht geladen werden!'); 
end; 


// Falls man die Namen der Icons in der Datei nicht kennt, kann man sie
// mit dem folgenden Code herausfinden. Die Namen werden in einem Memo
// aufgelistet, und bei Doppelklick auf eine Zeile des Memos, im Image angezeigt.

var 
  Datei: string = 'c:\windows\system32\shell32.dll'; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
  lib: THandle; 
begin 
  Memo1.clear; 
  Memo1.scrollbars := ssVertical; 
  lib := LoadLibraryEx(PChar(Datei), 0, LOAD_LIBRARY_AS_DATAFILE); 
  if lib <> 0 then begin 
    Memo1.Lines.BeginUpdate; 
    EnumResourceNames(lib, RT_GROUP_ICON, @Proc, Integer(Memo1.Lines)); 
    Memo1.Lines.EndUpdate; 
    FreeLibrary(lib); 
  end; 
end; 
 
procedure TForm1.Memo1DblClick(Sender: TObject); 
var 
  p: TPoint; 
  s: string; 
begin 
  p := Memo1.CaretPos; 
  s := Trim(Memo1.lines[p.y]); 
  if not LoadBigIcoFromLib(Datei, 
    PChar(s), Image1, 48, 48, clBtnFace, lrDefault, true) 
    then showmessage('Icon konnte nicht geladen werden!'); 
end; 



 

Zugriffe seit 6.9.2001 auf Delphi-Ecke