AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

SpeedButton - kein Bild?

Ein Thema von MarLe · begonnen am 29. Aug 2006 · letzter Beitrag vom 1. Sep 2006
Antwort Antwort
Seite 2 von 3     12 3      
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#11

Re: SpeedButton - kein Bild?

  Alt 30. Aug 2006, 13:44
Aha, kein Problem wenn das die sauberste Lösung darstellt.
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#12

Re: SpeedButton - kein Bild?

  Alt 30. Aug 2006, 13:56
Tja, das kommt drauf an. Wenn bereits ein Bild da ist, muss man erstmal überlegen, ob es auch anderswo noch verwendet wird. Wenn nicht, kann man es ohne Probleme überschreiben. Man kann dann sowohl das nillen als auch das Neu-Erzeugen weglassen. Ansonsten sollte man es freigeben, damit es nicht als Speicherleiche rumtreibt.
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#13

Re: SpeedButton - kein Bild?

  Alt 30. Aug 2006, 14:08
Du verwirrst mich jetzt wieder ein bisschen.
Muss ich nach dem Zuweisen des Bildes zusätzlich noch irgendwas unter finally freigeben???

Um das Bild generell wieder sauber loszuwerden reicht dann ein

SpeedButton1.Glyph := nil;
  Mit Zitat antworten Zitat
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#14

Re: SpeedButton - kein Bild?

  Alt 30. Aug 2006, 16:26
Sauber freigeben kannst du mit:
FreeAndNil(SpeedButton1.Glyph); Allerdings gibt es hier eine Exception, wenn dem Glyph noch kein Bitmap zugeordnet ist.
Außerdem sollte alles sauber freigegeben werden, wenn die Form - zu der der SpeedButton gehört - freigegeben wird, also wenn dein Programm beendet wird.

Diese Lösung halte ich nicht für besonders gut:
Delphi-Quellcode:
    SpeedButton1.Glyph := nil;
    SpeedButton1.Glyph := TBitmap.Create;
    SpeedButton1.Glyph.Width := ICO.Width;
    SpeedButton1.Glyph.Height := ICO.Height;
    SpeedButton1.Glyph.Canvas.Draw(0, 0, ICO);
Wenn noch Bildreste da sind, kannst du auch vorher einfach die Größe des Bitmaps auf 0 stellen, dann sollte nichts mehr vom alten Bild übrig sein:
Delphi-Quellcode:
    SpeedButton1.Glyph.Width := 0;
    SpeedButton1.Glyph.Height := 0;
    SpeedButton1.Glyph.Width := ICO.Width;
    SpeedButton1.Glyph.Height := ICO.Height;
    SpeedButton1.Glyph.Canvas.Draw(0, 0, ICO);
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#15

Re: SpeedButton - kein Bild?

  Alt 30. Aug 2006, 18:32
Zitat von Martin K:
Sauber freigeben kannst du mit:
FreeAndNil(SpeedButton1.Glyph);
Martin, diesen Code hast du nicht getestet, stimmts? Der Compiler meiner Delphi-Version wollte die Zeile jedenfalls nicht...

Zitat:
Allerdings gibt es hier eine Exception, wenn dem Glyph noch kein Bitmap zugeordnet ist.
Warum sollte es in diesem Fall eine Exception geben?


Noch eine Anmerkung zur Funktion ExtractAssociatedIcon: diese erwartet im zweiten Parameter einen Zeiger auf einen Zeichenpuffer. Sie liefert in diesem Puffer den vollständigen Pfad- und Dateinamen der ausführbaren Datei zurück, in dem das Icon gefunden wurde. Die Übergabe eines dynamischen Strings oder gar einer String-Eigenschaft (Edit1.Text) wird somit früher oder später zu Abstürzen führen. Richtiger wäre es, einen Puffer geeigneter Größe bereitzustellen, diesen mit dem gewünschten Dateinamen zu füllen und schließlich den Puffer an die Funktion zu übergeben:

Delphi-Quellcode:
var
  buf : array [0..max_path] of char;
begin
  buf := 'yourfile.exe';
  ExtractAssociatedIcon(hInstance, buf, IconIndex);
end;
Gruß Hawkeye
  Mit Zitat antworten Zitat
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#16

Re: SpeedButton - kein Bild?

  Alt 30. Aug 2006, 19:16
Zitat von Hawkeye219:
Zitat von Martin K:
Sauber freigeben kannst du mit:
FreeAndNil(SpeedButton1.Glyph);
Martin, diesen Code hast du nicht getestet, stimmts? Der Compiler meiner Delphi-Version wollte die Zeile jedenfalls nicht...
Sorry, stimmt ja...
Weil SpeedButton1 ein Objekt ist und keine Variable.
Aber mit:
SpeedButton1.Glyph.Free; sollte es klappen.

Aber wie gesagt, viel Sinn macht das nicht, da der SpeedButton und somit auch Glyph zusammen mit der Form freigegeben wird.
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#17

Re: SpeedButton - kein Bild?

  Alt 30. Aug 2006, 19:26
Das ist nicht nur sinnlos, sondern führt auch beim nächsten Klick auf den Button zum Absturz der Applikation. Das Glyph-Objekt wurde vom SpeedButton erzeugt und darf auch nur von diesem freigegeben werden. Die Zuweisung

Speedbutton1.Glyph := NIL; löscht nicht das Glyph-Objekt, sondern nur den Inhalt der Bitmap. Das Glyph-Objekt wird erst bei der Freigabe des Speedbuttons von diesem zerstört.

Gruß Hawkeye
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#18

Re: SpeedButton - kein Bild?

  Alt 31. Aug 2006, 12:28
Hab's jetzt wie folgt umgesetzt:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  ICO: TIcon;
  Large, Small: HIcon;
  IconIndex: Word;
  buf: array[0..max_path] of char;
begin
  ICO := TIcon.Create;
  try
    StrPCopy(buf, Edit1.Text);
    IconIndex := 0;
    ICO.Handle := ExtractAssociatedIcon(hInstance, buf, IconIndex);
    SpeedButton1.Glyph.Width := 0;
    SpeedButton1.Glyph.Height := 0;
    SpeedButton1.Glyph.Width := ICO.Width;
    SpeedButton1.Glyph.Height := ICO.Height;
    SpeedButton1.Glyph.Canvas.Draw(0, 0, ICO);
    //SpeedButton1.Refresh;
  finally
    ICO.Free;
  end;
end;
... und Bild wieder entfernen:

Delphi-Quellcode:
procedure TForm1.ButtonResetClick(Sender: TObject);
begin
  SpeedButton1.Glyph := nil;
end;
Die Bildqualität ist teilweise aber ziehmlich mies (ist mir bei vorherigen Versuchen gar nicht so aufgefallen).
Kann man da noch was machen, die sollten eigentlich so ausschauen wie z.B. auf dem Desktop.
  Mit Zitat antworten Zitat
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#19

Re: SpeedButton - kein Bild?

  Alt 31. Aug 2006, 13:38
Ich glaub jetzt habe ich die Lösung:

Das mit der "miesen Bildqualität" liegt wohl am Alpha-Kanal der 32 Bit-Icons - das von dem alten Icon noch Reste übrig waren wenn ein neues drübergemalt wurde, liegt an der Transparenz der Icons.
Da ein leeres Bitmap immer weiß ist, bleiben die Stellen wo eine Halbtransparenz beim Alpha-Kanal des Icons ist, beim Bitmap weiß.

Lösung:
Einfach das Bitmap vorher komplett in die Farbe der Form (clBtnFace) einfärben, so wird als transparente Farbe clBtnFace verwendet und nicht mehr weiß.
Der Alpha-Kanal wird nun mit clBtnFace und nicht mehr in weiß dargestellt.

Des Weiteren verschwindet durch das Einfärben in clBtnFace das alte Bitmap komplett und es bleiben keine Reste mehr.
Somit wird die Zuweisung des Bitmaps auf NIL oder das Setzen der Größe des Bitmaps (Width und Height) auf 0 überflüssig.

Außerdem kannst Du die nicht verwendeten Variablen Large, Small: HIcon; logischerweise weglassen.

So sähe es dann aus:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  ICO: TIcon;
  IconIndex: Word;
  buf: array[0..max_path] of Char;
begin
  ICO := TIcon.Create;
  try
    StrPCopy(buf, Edit1.Text);
    IconIndex := 0;
    ICO.Handle := ExtractAssociatedIcon(hInstance, buf, IconIndex);
    SpeedButton1.Glyph.Width := ICO.Width;
    SpeedButton1.Glyph.Height := ICO.Height;
    SpeedButton1.Glyph.Canvas.Brush.Color := Color; //Farbe der Form
    SpeedButton1.Glyph.Canvas.FillRect(Rect(0, 0, SpeedButton1.Glyph.Width, SpeedButton1.Glyph.Height)); //Bitmap füllen
    SpeedButton1.Glyph.Canvas.Draw(0, 0, ICO);
  finally
    ICO.Free;
  end;
end;
... und Bild wieder entfernen:
Delphi-Quellcode:
procedure TForm1.ButtonResetClick(Sender: TObject);
begin
  SpeedButton1.Glyph.Canvas.Brush.Color := Color;
  SpeedButton1.Glyph.Canvas.FillRect(Rect(0, 0, SpeedButton1.Glyph.Width, SpeedButton1.Glyph.Height));
end;
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#20

Re: SpeedButton - kein Bild?

  Alt 31. Aug 2006, 14:03
Die weißen Ränder sind jetzt weg, aber an der Bildqualität hat sich nicht's geändert.
z.B. wird das schwarze Verknüpfungssymbol von Windows grau dargestellt.
Hab mal gegoogelt und den Artikel
http://www.aboutvb.de/khw/artikel/khwassocicon.htm
gefunden. Da steht u.a. das die ExtractAssociatedIcon-Funktion, wie gesagt, nur bedingt brauchbar ist
und man besser auf die SHGetFileInfo-Funktion zurückgreifen sollte.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz