Autor Beitrag
Stefan S.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 184


D5
BeitragVerfasst: Do 12.10.06 22:08 
Hallo allerseits.
Ich habe in einem Programm eine Stelle, an der sich die Schriftgröße eines Panels dynamisch der Länge des der Caption-Eigenschaft zugewiesenen Textes anpasst, also so, dass die Schrift immer so groß wie möglich ist, aber nie am Rand rausragt. Dazu erstelle ich ein TBitmap, mit dessen Canvas.Font-Eigenschaft ich dann rumexperimentieren lasse, um am Ende die Länge des Textes in Pixeln mit der Width des Panels vergleichen zu können. Die eigentliche Funktion ist nicht das Problem, sondern das TBitmap: Nachdem ich mit "FontBitmap" gearbeitet habe, möchte ich es mit "FontBitmap.Free" wieder auflösen, aber durch diese Programmzeile wird aus irgendeinem mir schleierhaften Grund eine Zugriffsverletzung verursacht. Ich bin mir sicher, dass sie durch das ".Free" zustande kommt, denn wenn ich die Zeile rauskommentiere, kommt keine Fehlermeldung.

Wodurch könnte die Zugriffsverletzung verursacht werden? Und wie ist das überhaupt mit ".Free", braucht es das unbedingt? Was ist, wenn man es weglässt und der Speicher nicht wieder freigegeben wird? Häufen sich dann Speicherbelegungen von unbenutzen TBitmaps?

Hier der Code (FontBitmap ist noch unter var als TBitmap definiert):

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
FontBitmap := TBitmap.Create;
FontBitmap.Canvas.Font := Form2.Panel1.Font;

//ab hier wird jetzt mit dem Canvas von FontBitmap gearbeitet
//das ist für die meisten wohl nicht ganz verständlich und eigentlich auch unrelevant

If Screen.Width = 800 then
 FontBitmap.Canvas.Font.Size := 16
Else If Screen.Width = 1280 then
 FontBitmap.Canvas.Font.Size := 20
Else
 FontBitmap.Canvas.Font.Size := 18;
While (FontBitmap.Canvas.Textwidth(Frage) > Form2.Panel1.Width+2and  
      (FontBitmap.Canvas.Font.Size > 12do
  FontBitmap.Canvas.Font.Size := FontBitmap.Canvas.Font.Size - 1;
Form2.Panel1.Font.Size := FontBitmap.Canvas.Font.Size;
//
FontBitmap.Canvas.Font := Form2.Panel2.Font;
If Screen.Width = 800 then
  FontBitmap.Canvas.Font.Size := 14
Else If Screen.Width = 1280 then
  FontBitmap.Canvas.Font.Size := 18
Else
  FontBitmap.Canvas.Font.Size := 16;
While ((FontBitmap.Canvas.Textwidth(Antwort1) > Form2.Panel2.Width+2)
    or (FontBitmap.Canvas.Textwidth(Antwort2) > Form2.Panel3.Width+2)
    or (FontBitmap.Canvas.Textwidth(Antwort3) > Form2.Panel4.Width+2))
    and (FontBitmap.Canvas.Font.Size > 12do
  FontBitmap.Canvas.Font.Size := FontBitmap.Canvas.Font.Size - 1;
Form2.Panel2.Font.Size := FontBitmap.Canvas.Font.Size;
Form2.Panel3.Font.Size := FontBitmap.Canvas.Font.Size;
Form2.Panel4.Font.Size := FontBitmap.Canvas.Font.Size;

FontBitmap.Free;


Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Do 12.10.06 22:16 
Hallo,

wird wohl mit der Zuweisung in Zeile 2 und 18 zusammenhängen (FontBitmap.Canvas.Font := Form2.Panel1.Font;). Du weisst dem Canvas ein Fontobjekt zu, dass dan freigeben wird, siehe unten. Kopier das Fontobjekt oder weiss nur die entsprechenden Eigenschaften zu.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
destructor TCanvas.Destroy;
begin
  CanvasList.Remove(Self);
  SetHandle(0);
  FFont.Free;
  FPen.Free;
  FBrush.Free;
  DeleteCriticalSection(FLock);
  inherited Destroy;
end;

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
Stefan S. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 184


D5
BeitragVerfasst: Fr 13.10.06 15:40 
user profile iconwulfskin hat folgendes geschrieben:
Du weisst dem Canvas ein Fontobjekt zu, dass dan freigeben wird, siehe unten. Kopier das Fontobjekt oder weiss nur die entsprechenden Eigenschaften zu.


Sorry, aber da bin ich grad etwas schwer von Begriff... Wo müsste ich den Code den du vorgeschlagen hast einfügen?

Ich hab es aber schon mal mit letzterem Tipp versucht, nämlich nur die entsprechenden Eigenschaften zuzuweisen:

Statt

ausblenden Delphi-Quelltext
1:
FontBitmap.Canvas.Font := Form2.Panel1.Font;					


hab ich nun

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
FontBitmap.Canvas.Font.Charset := Form2.Panel1.Font.Charset;
FontBitmap.Canvas.Font.Size := Form2.Panel1.Font.Size;
FontBitmap.Canvas.Font.Name := Form2.Panel1.Font.Name;
FontBitmap.Canvas.Font.Height := Form2.Panel1.Font.Height;
FontBitmap.Canvas.Font.Pitch := Form2.Panel1.Font.Pitch;
FontBitmap.Canvas.Font.Style := Form2.Panel1.Font.Style;


Aber es ändert nichts. Die Fehlermeldung kommt nach wie vor.

EDIT: Kurios: In einem anderen Formular wende ich genau den selben Code für genau den selben Zweck an, aber da kommt keine Zugriffsverletzung...
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Fr 13.10.06 18:31 
Hast du die beide Zuweisungen durch deinen Code ersetzt (siehe mein Beitrag)? Ansonsten klammer die mal die ganzen dinge, die mit der Schriftart zu tun haben, aus und schau ob es dann klappt.
Ich bin mir eigentlich schon recht sicher, dass es mit dem Font-Objekt zusammen hängt.

Achja, der Quelltext zu Canvas.Destroy hab ich nur hinzugefügt um ein Mal zu zeigen, wie man solche Fehler finden kann, vorausgesetzt man hat die Quelltexte der Units...

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
Stefan S. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 184


D5
BeitragVerfasst: Sa 14.10.06 16:54 
Ja, ich habe es bei beiden so ersetzt wie ich es gezeigt habe, also bei "FontBitmap.Canvas.Font := Form2.Panel1.Font;" und bei "FontBitmap.Canvas.Font := Form2.Panel2.Font;" weiter unten.
Hab jetzt mal wie du gesagt hast alle Font-Zuweisungen für FontBitmap.Canvas rauskommentiert, es bleiben also nur noch "FontBitmap := TBitmap.Create" und "FontBitmap.Free". Die Meldung kommt weiterhin... Wenn ich das "FontBitmap.Free" rauskommentiere ist weiterhin alles in Ordnung.
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: So 15.10.06 19:12 
Hallo,

dann greifst du wohl nochmal auf das Bitmap zu. Ich müsste den Quelltext sehen, um das beurteilen zu können.

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
Stefan S. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 184


D5
BeitragVerfasst: Mo 16.10.06 16:25 
Oh mein Gott. Sowas blödes.
Du hast recht gehabt! :) Ich wollte mir durch die Suchfunktion Gewissheit verschaffen, dass FontBitmap wirklich nur an dieser einen Stelle gebraucht wird, aber dabei bin ich darauf gestoßen, dass FontBitmap kurz nach dem "FontBitmap.Free" tatsächlich nochmal auftaucht - nämlich hab ich mir anfangs mal zu Testzwecken den Wert von FontBitmap.Canvas.Textwidth in Form2.Caption schreiben lassen und vergessen, das wieder zu entfernen oder zumindest weiter nach vorne zu setzen, als ich das "FontBitmap.Free" hinzugefügt habe.
Wie peinlich... ^^ Tut mir Leid um die viele Mühe und vielen Dank nochmal. Es sind eben doch immer die einfachsten Fehler, die man nicht findet...