Autor Beitrag
Reinhard Kern
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: So 24.09.06 00:33 
Hallo,

wie man aus der Diskussion sieht, ist ein Canvas (egal welcher) nicht geeignet zur Bestimmung der Textlänge. Dafür gibt es noch mehr Gründe als hier bereits aufgetaucht sind: ich wollte StringGrids auf verschiedenen Pages einer PageControl ausrichten, aber auf den nicht aktiven Seiten ist auch der Canvas nicht aktiv und liefert TextWidth = 0 für alle Strings :-(

Lösung: Windows-API. Canvas ist einfach eine sehr unvollständige Abbildung davon. Da ich die Textlänge auf dem Bildschirm wissen will, hole ich mir den Screen DC mit GetDC (0) und die Textlänge dann mit GetTextExtentPoint. Das berücksichtigt sogar variable Zeichenabstände.

Gruss Reinhard
Stefan S. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 184


D5
BeitragVerfasst: Fr 29.09.06 23:50 
Vielen Dank, Lannes, mit der Bitmap-Methode funktioniert es wunderbar und es gibt kein Geblinke mehr im Formular.
Nur eine kleine Frage: Wenn ich am Ende des Codes, der die Schriftgröße bestimmt, das Bitmap mit "bla.Free;" wieder auflösen lasse, wird eine Zugriffsverletzung gemeldet. Liegt das etwa daran, dass der Code in einer eigenen Prozedur von mir steht? Und ist das "Freigeben" überhaupt unbedingt nötig? (Ich habe tatsächlich noch nie zur Laufzeit Komponenten erstellt, deshalb kenne ich mich da nicht aus.)
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Sa 30.09.06 22:13 
Hallo,

user profile iconReinhard Kern hat folgendes geschrieben:
...ich wollte StringGrids auf verschiedenen Pages einer PageControl ausrichten, aber auf den nicht aktiven Seiten ist auch der Canvas nicht aktiv und liefert TextWidth = 0 für alle Strings :-(...
nicht ganz richtig, das Canvas ist aktiv sobald das entsprechende Grid einmal sichtbar gewesen ist, also schon mal gezeichnet wurde.

user profile iconStefan S. hat folgendes geschrieben:
...Nur eine kleine Frage: Wenn ich am Ende des Codes, der die Schriftgröße bestimmt, das Bitmap mit "bla.Free;" wieder auflösen lasse, wird eine Zugriffsverletzung gemeldet. Liegt das etwa daran, dass der Code in einer eigenen Prozedur von mir steht?
vermute das die Zugriffsverletzung nicht beim Free liegt, mit Code oder/und mehr Informationen kann man mehr dazu sagen. Hast Du das Bitmap auch mit bla := TBitmap.Create; erzeugt bevor Du darauf zugreifst?

user profile iconStefan S. hat folgendes geschrieben:
Und ist das "Freigeben" überhaupt unbedingt nötig? (Ich habe tatsächlich noch nie zur Laufzeit Komponenten erstellt, deshalb kenne ich mich da nicht aus.)
nicht immer unbedingt nötig, aber besser und sauberer programmiert, Du willst das System ja nicht mit nicht mehr benötigten Speicher belasten.

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
Stefan S. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 184


D5
BeitragVerfasst: So 01.10.06 12:15 
Die Zugriffsverletzung tritt an der Stelle auf, an denen der Code angewandt wird und sie kommt nicht, wenn ich das "bla.Free;" mit "//" rauskommentiere.

Der Code (ich weiss, ich hab einen unsauberen Programmierstil):

ausblenden volle Höhe 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 dich wahrscheinlich nicht ganz verständlich und wohl 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+2) and  
      (FontBitmap.Canvas.Font.Size > 12) do
  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 > 12) do
  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;


FontBitmap habe ich dann oben unter "var" noch als TBitmap definiert. Das war's.

EDIT: Das Problem ist mittlerweile gelöst.