Entwickler-Ecke

Windows API - XP-Icons in Resourcen Datei?!?


FD-83 - So 27.07.03 02:11
Titel: XP-Icons in Resourcen Datei?!?
Ich habe eine *.rc Datei mit brcc32.exe in eine Resourcen Datei compiliert.

Die rc-Datei sieht so aus:

1 ICON "Dateiname1"
2 ICON "Dateiname2"
usw.

Die Ressourcen Datei binde ich dann mit {$R Icons.res} in mein Projekt ein.

Nun sind zusätzlich zu dem Exe-Icon was ja schon von Delphi aus drin ist noch eigene Icons in der Exe-Datei enthalten.

Wenn ich jetzt mit ExtractIconEx das erste Icon (also das Exe-Icon das Delphi eingefügt hat) extrahiere und dann mit DrawIcon auf ein Canvas Zeichne wird AlphaBlending unterstützt. (Da ich WindowsXP habe und das Icon in den Farbtiefen 16Farben, 256Farben & TrueColor+Alpha vorliegt).

Soweit so gut. Aber wenn ich jetzt eins von den Icons aus meiner ResourcenDatei aus der Programmdatei extrahiere und auf ein Canvas zeichne benutzt Windows komischerweise "nur" die 256 Farben Version. Obwohl die Icons in der Ressorcen Datei auch jeweils in TrueColor+Alpha vorhanden sind!

Wie kommt das?!? Und was kann ich machen?

Gruss Frederik


derDoc - So 27.07.03 13:49

Schreibe doch mal deinen Quellcode.

Ich hatte mal ein ähnliches Programm, hier ist mal meine Debugeinheit:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.Button1Click(Sender: TObject);
var
  count, Test: Integer;
  LargeIconHandle, SmallIconHandle: HICON;
begin
  OpenDialog1.Execute; //Datei auswählen
  count := 1//1 Icon holen
  Label1.Caption := OpenDialog1.FileName; //Überprüfung für Dateiname
  Test := ExtractIconEx(PChar(Label1.Caption), -1, LargeIconHandle, SmallIconHandle, count); //Anzahl der Icons
  ExtractIconEx(PChar(Label1.Caption), 0, LargeIconHandle, SmallIconHandle, count); //erstes Icon holen
  Image1.Picture.Icon.Handle := LargeIconHandle; //In Image anzeigen
  Label2.Caption := IntToStr(Test); //Anzahl Icons ausgeben
  Form1.Canvas.Draw(2020, Image1.Picture.Graphic); //Auf Canvas zeichnen
end;


FD-83 - So 27.07.03 14:00

Also das Extrahieren klappt ja. Nur kann man ja nicht beeinflussen in welcher Farbtiefe Windows das Icon extrahiert. Normalerweise nimmt er das beste was da ist und das System anzeigen kann. Das wäre in meinem Fall das True Color Icon mit Alpha blending. Das macht er auch bei allen anderen Exe-, dll- und icl-Dateien! Auch das Programmicon das von Delphi mit in die Exe-Datei kompiliert wird, extrahiert die API in TrueColor+Alpha nur eben die Icons die in meiner Resourcendatei waren nicht. Da nimmt er immer nur die 256 Farb versionen.

Mit einem Programm ("Microangelo") oder einem Resource Hacker sehe ich auch, dass die Icons in der entsprechenden Farbtiefe in der Exe-Datei vorhanden sind. Nur aus irgendeinem schwachsinnigen Grund werden sie nicht benutzt...

Gruss Frederik


derDoc - So 27.07.03 14:16

Ich habe bei mir noch ein bischen getestet und aus der *.exe die ich teste alle Icons die drin waren als 32bit Alpha erhalten.


FD-83 - So 27.07.03 15:15

OK wenn dem Wirklich so ist, beschreib ich nochmal genau was ich gemacht habe. Vllt mach ich ja was anders/falsch:

Also Ich habe eine Delphi 7 Anwendung. Unter "Projekt" --> "Optionen" --> "Anwendung" kann ich der Exe-Datei ein Symbol zuweisen. Dort wäöhle ich ein Icon aus.

Jetzt erstelle ich mit einem Texteditor eine .rc Datei die wie folgt aussieht:

1 ICON Name.ico
2 ICON Name2.ico
3 ICON Name3.ico

Dann erstelle ich mit dem Befehl "brcc32.exe Icons.rc" die Resourcen Datei.

Diese binde ich mit {$R Icons.res} in das Programm ein.

Dann führe ich folgenden Code aus:

Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure Test;
Var
  LgIcon, SmIcon: hIcon;
begin
  ExtractIconEx(PChar(Application.ExeName),2,LgIcon,SmIcon,1);
  DrawIcon(Canvas.Handle,100,100,lgicon);
end;

Das Resultet ist, dass das 2. Icon aus der Resourcen Datei auf die Form gezeichnet wird. Allerdings wie gesagt nicht mit Alpha Kanal sondern nur die 256 Frab Version.

Hast du da was anders gemacht?

Gruss Frederik


derDoc - So 27.07.03 20:44

Ich habe das so gemacht, wie ich es oben schonmal beschrieben hatte, nur mit der Änderung. Dieses wurde dann auch korrekt in 32Bit Alpha angezeigt.

Hier ist nun meine Testvariante:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
OpenDialog1.Execute;
  count := 1;
  Label1.Caption := OpenDialog1.FileName;
  test := ExtractIconEx(PChar(Label1.Caption), -1, LargeIconHandle, SmallIconHandle, count);
  ExtractIconEx(PChar(Label1.Caption), 0, LargeIconHandle, SmallIconHandle, count);
  Image1.Picture.Icon.Handle := LargeIconHandle;
  Label2.Caption := IntToStr(test);
  Form1.Canvas.Draw(2020, Image1.Picture.Graphic);
  DrawIcon(Form1.Canvas.Handle, 5080, LargeIconHandle);
  Label1.Caption := ExtractFileName(Label1.Caption);


Das Icon in der Resource lag als 48², 32² und 16² in 32Bit, 8Bit und 4Bit vor. Es wurde immer bei LargeIconHandle 32x32 32Bit bzw. bei SmallIconHandle 16x16 32Bit benutzt.