![]() |
Application.Icon setzen
Hallo,
in meiner App erscheint zuerst ein SpashScreen. Das ist eine einfache TForm. Das Hauptformular wird erst später geladen. Ich möchte nun dass in der Taskleiste nun gleich ein Icon und der Titel erscheint. Beim Titel klappt das mit Application.Titel recht gut, beim Icon gelingt es mir nicht. Wie macht man das am Besten, woran kann es liegen? Letzter Versuch war:
Delphi-Quellcode:
cxImageListMainIcon ist dabei einem Imagelist. Mit einem TImage gings auch nicht. Auch nicht mit SplashForm.Icon.Icon := TIcon.Create; try SplashForm.cxImageListMainIcon.GetIcon(0, Icon); Application.Icon.Assign(Icon); finally Icon.Free; end; Für Ideen oder eine Lösung wäre ich dankbar. |
AW: Application.Icon setzen
Delphi-Quellcode:
Application.Icon := SplashForm.cxImageListMainIcon.GetIcon(0, Icon);
sollte eigentlich funktionieren. |
AW: Application.Icon setzen
Danke. Leider Nein: [DCC Fehler] Fm_Splash.pas(70): E2010 Inkompatible Typen: 'TIcon' und 'procedure, untyped pointer or untyped parameter': GetIcon ist keine function.
(PS.: gegooglet habe ich auch schon lange.) |
AW: Application.Icon setzen
Mein Fehler. So natürlich:
Delphi-Quellcode:
IconX := SplashForm.cxImageListMainIcon.GetIcon(0, Icon);
Application.Icon := IconX; |
AW: Application.Icon setzen
Sorry, dadurch wird GetIcon immer noch nicht zu einer function ;-)
|
AW: Application.Icon setzen
So hole ich mir zur Laufzeit Icons aus der Resource:
Delphi-Quellcode:
{$R MYICONS.RES}
procedure TForm1.Button1Click(Sender: TObject); var h : hIcon; begin h := LoadIcon(hInstance, 'ICON_1'); Application.Icon.Handle := h; InvalidateRect(Application.Handle, nil, true); end; |
AW: Application.Icon setzen
Na dann jetzt aber nochmal richtig ...
Delphi-Quellcode:
oder direkt ohne Zwischenvariable
SplashForm.cxImageListMainIcon.GetIcon(0, Icon);
Application.Icon := Icon;
Delphi-Quellcode:
SplashForm.cxImageListMainIcon.GetIcon(0, Application.Icon);
|
AW: Application.Icon setzen
Funktioniert leider auch nicht - außer dass es später eine Schutzverletzung gibt (vermutlich weil es dann SplashForm und soit auch das Icon nicht mehr gibt.)
@KodeZwerg: Danke. Das sieht jetzt eher lowlevel aus. Versucht habe ich es so:
Delphi-Quellcode:
Es funktionert aber auch nicht. Nach dem Debugger hat h einen Wert. Nach der Doku ("If the function succeeds, the return value is a handle to the newly loaded icon. If the function fails, the return value is NULL. To get extended error information, call GetLastError.") müsste das Laden ja dann geklappt haben weil h ist ja nicht NULL.
h := LoadIcon(hInstance, 'MAINICON');
Application.Icon.Handle := h; InvalidateRect(Application.Handle, nil, true); Application, Application.Icon.Handle und Application.Handle habe nach Debugger auch was drin. Das Icon erscheint aber nicht bei mir. Ich habe den Verdacht dass mir DevExpress da noch irgendwie reinspuckt. Aufgrund von ![]()
Delphi-Quellcode:
Ich gebs mal vorläufig auf.
var
hApp: HWND; hSmall : hIcon; hLarge : hIcon; begin hApp := Application.Handle; hSmall := LoadImage(HInstance, 'MAINICON', IMAGE_ICON,16, 16, 0); hLarge := LoadImage(HInstance, 'MAINICON', IMAGE_ICON,256, 256, 0); SendMessage(hApp, WM_SETICON, ICON_SMALL, hSmall) ; SendMessage(hApp, WM_SETICON, ICON_BIG, hLarge) ; InvalidateRect(hApp, nil, true); UpdateWindow(hApp); end; |
AW: Application.Icon setzen
Delphi-Quellcode:
Also in MyIcons.res existiert ein Icon was den Namen "ICON_1" bekommen hat, dem System ist in der Regel die Größe egal da es von selbst runter/hoch skaliert. Ich hab keinen Check drinn da die Resource bei mir immer existiert. Ob es LowLevel ist kann ich nicht sagen, nur das es bei mir auf diese Weise klappt kann ich sagen.
{$R MYICONS.RES}
procedure TForm1.Button1Click(Sender: TObject); var h : hIcon; // wir brauchen das Handle, nicht das Image, deswegen HICON begin h := LoadIcon(hInstance, 'ICON_1'); // in Resource-Datei MyIcons.res ist ein Eintrag Namens ICON_1, Handle dahin erzeugen Application.Icon.Handle := h; // Handle an das Programm übergeben InvalidateRect(Application.Handle, nil, true); // Programm update end;
Code:
sollte das WinApi Äquivalent sein und genügen.
SendMessage(hApp, WM_SETICON, ICON_BIG, h);
Ich vermute LoadImage() macht nicht das gleiche wie LoadIcon().
Code:
Probier's mal so.
SendMessage(hApp, WM_SETICON, ICON_BIG, LoadIcon(hInstance, 'MAINICON'));
|
AW: Application.Icon setzen
Zitat:
Delphi-Quellcode:
SplashForm.cxImageListMainIcon.GetIcon(0, Application.Icon);
|
AW: Application.Icon setzen
Ungetestet als Idee hingedaddelt:
Delphi-Quellcode:
Icon := TIcon.Create;
st := TMemoryStream.Create; try SplashForm.cxImageListMainIcon.GetIcon(0, Icon); Icon.SaveToStream(st); Application.Icon.LoadFromStream(st); finally st.Free; Icon.Free; end; |
AW: Application.Icon setzen
@freimatz
Kann es sein, das du das etwas kompliziert machst? Warum kopierst du soviel herum? Wenn du ein Icon hast, dann übergibt Application die Adresse und gut ist es. Das habe ich auf die Schnelle gemacht. Ich habe auf dem Formular eine TImage abgelegt, ein Icon rein geladen, und es übergeben. Funktioniert.
Delphi-Quellcode:
Dann habe ich noch zwei andere versuche unternommen. Funktionieren auch.
program Project1;
uses Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Title := 'Dies und Das'; //Application.Icon.Handle := Form1.Image1.Picture.Icon.Handle; //Funktioniert //Application.Icon := Form1.Image1.Picture.Icon; //Funktioniert Application.Icon := Form1.Icon; //Funktioniert Application.Run; Application.Icon.Assign(Icon); end. Hier ein anderes Beispiel, mal schnell ein Splashscreen eingebaut (Form2)
Delphi-Quellcode:
program Project1;
uses Forms, Unit1 in 'Unit1.pas' {Form1}, Unit2 in 'Unit2.pas' {Form2}; {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.CreateForm(TForm2, Form2); Application.Title := 'Dies und Das'; Application.Icon := Form2.Icon; Form2.ShowModal; // Nach 2 Sekunden schließt sich Form2 selbst. Application.Icon := Form1.Icon; Application.Run; end.
Delphi-Quellcode:
Nach 2 Sekunden wechselt das Icon erneut.
unit Unit2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TForm2 = class(TForm) Timer1: TTimer; procedure Timer1Timer(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.Timer1Timer(Sender: TObject); begin if Timer1.Tag = 2000 then Close; Timer1.Tag := Timer1.Tag + Timer1.Interval; end; end. |
AW: Application.Icon setzen
Zitat:
Leider habe ich noch mehr als 500.000 andere Zeilen Code die halt auch im Projekt drin sein müssen sonst werden manche Leute unzufrieden ;-) |
AW: Application.Icon setzen
Wieso beeinflussen die anderen 500.000 Zeilen denn Application.Icon?
|
AW: Application.Icon setzen
Tja, wenn ich das wüsste ... :?
Wie geschrieben habe ich DevExpress im Verdacht. Die hooken sich ins System rein. Allerdings hatte ich noch keine Zeit das näher zu untersuchen. |
AW: Application.Icon setzen
In aktuellen Delphis ist standardmäßig nicht das Application.Icon in der Taskleiste zu sehn, sondern Application.MainForm.Icon, denn
![]() Du könntest beim Programmstart MainFormOnTaskbar umstellen, aber anschließend sollte es besser immer auf True stehen, denn in Bezug auf Aero Peek und das Kontextmenü des Taskbuttons hat es einen großen Einfluss. |
AW: Application.Icon setzen
Ah danke. Das hatte ich noch nicht "auf dem Schirm". Werde das untersuchen.
|
AW: Application.Icon setzen
Zitat:
|
AW: Application.Icon setzen
Zitat:
|
AW: Application.Icon setzen
Ich handhabe es so, dass der Splash-Screen für die Dauer angezeigt wird die es benötigt alle Formulare zu erzeugen + 500 Millisekunden.
Natürlich ist er ausschaltbar. |
AW: Application.Icon setzen
Hallo,
also erstmal - ich habe eine Lösung:
Delphi-Quellcode:
An sich fehlte gegenüber vorigen Versuchen nur ein "Application.ProcessMessages();"
procedure DoIcon();
var h : hIcon; begin h := LoadIcon(hInstance, 'MAINICON'); Application.Icon.Handle := h; InvalidateRect(Application.Handle, nil, true); end; begin Application.Title := 'BalBlaBla'; DoIcon(); Application.Initialize; SplashFormCreate('',false); Application.ProcessMessages(); ... Zitat:
Zwischen Programmstart und bis das Hauptfenster fertig ist können schon mal 10 Sekunden vergehen. Application.MainFormOnTaskbar ist von Beginn an False; ob das später noch mal auf True geht habe ich nicht untersucht. Das Hauptfenster setzt später auch nochmal das Icon (je nach Konfiguration unterschiedliche) Mein Splash ist nicht ausschaltbar; andererseits ist er auch nicht fsStayOnTop so dass man noch was anders tun kann. Danke für alle Beiträge. :thumb: |
AW: Application.Icon setzen
Solange der Splash-Screen nur für die Dauer des Programmstarts angezeigt wird, wenn auch wirklich was geladen/initialisiert wird, ist doch alles OK. Nag-Screen kann man das nicht nennen.
Sonst wäre der Photoshop-Splash-Screen ja auch ein Nag-Screen. |
AW: Application.Icon setzen
So sollts auch gehen um Code kurz zu halten.
Delphi-Quellcode:
Sonst müsstest Du irgendwo das "h" wieder freigeben, oder?
procedure DoIcon();
begin Application.Icon.Handle := LoadIcon(hInstance, 'MAINICON'); InvalidateRect(Application.Handle, nil, true); end; |
AW: Application.Icon setzen
Programmierung Lehrjahr 1: Zwischenvariablen, wenn möglich, immer vermeiden. Besonders bei Blöcken <= 10 Zeilen.
|
AW: Application.Icon setzen
In der Entstehung nutz ich erstmal viele Variablen um halt Feedback auswerten zu können, die kommen alle schön brav in eine {$IFNDEF DEPLOY} rein um automatisch bei {$DEFINE DEPLOY} ignoriert/übersprungen zu werden.
Als Beispiel dient mir obiger Source:
Delphi-Quellcode:
Habs grad nur so hingekritzelt, korrektheit könnt falsch sein.
{.$DEFINE DEPLOY} // Wenn der Punkt entfernt wird, ist's aktiv
procedure DoIcon(); {$IFNDEF DEPLOY} var h : hIcon; {$ENDIF DEPLOY} begin {$IFNDEF DEPLOY} h := LoadIcon(hInstance, 'MAINICON'); Application.Icon.Handle := h; {$ELSE DEPLOY} Application.Icon.Handle := LoadIcon(hInstance, 'MAINICON'); {$ENDIF DEPLOY} InvalidateRect(Application.Handle, nil, true); end; |
AW: Application.Icon setzen
Sieht schwer noch nahezu doppeltem und unheimlich schwer wartbarem Code aus wenn es dann mal tausende Zeilen sind die man so schreibt.
|
AW: Application.Icon setzen
Zitat:
Programmierung Lehre -> diese Schule meiden. Ok - schöner Code ist meiner auch nicht. Aber da mache ich erst wieder rum wenn das Produkt raus ist und das ist Donnerstag. @KodeZwerg: was soll das bringen? Macht es doch nur extrem unleserlich. Der Compiler optimiert das doch eh weg. |
AW: Application.Icon setzen
Zitat:
Wenn man einen Wert in einem Code-Block x-mal benötigt ist das was anderes. |
AW: Application.Icon setzen
Das war halt nur ein Beispiel, jeder so wie er es mag.
Da ich mich an so eine Art der Programmierung gewöhnt habe, also das innerhalb bestimmter {$IF} Blöcke nur bestimmte Sachen beim Compilieren berücksichtigt werden, kann ich mich halt in den {$IFNDEF} Blöcken relativ frei austoben und in den {$IFDEF} oder {$ELSE} Blöcken halt Achten alles richtig zu machen. Da es bei mir viele eigene Funktionen/Prozeduren gibt die ich halt in zwei Varianten brauche, einmal Testing einmal Release ohne jede Funktion/Prozedur doppelt haben zu müssen, nutze ich diese Möglichkeit. Punkt entfernen = nur Release Code wird compiliert und das betrifft bei mir halt viele Aufrufe. |
AW: Application.Icon setzen
Beim Debuggen kann man sich die Zwischenergebnisse ansehen. (OK, im Assembler, teilschritte in den überwachten Ausdrücke, Variable auswerten, ...)
Zitat:
Vieles wird selten/fast nie verwendet, oder schaust du dir den Options- oder gar den Info-Dialog deines Delphi mehrmals täglich an? |
AW: Application.Icon setzen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:56 Uhr. |
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