GetStringMetricsOnDC()
Verfasst: 09.12.2006 21:53
Erklärung:
Gibt die Größe und Breite eines Strings mit vorher festgelegten Font (DrawingFont()) in Pixeln auf einem DC zurück (StartDrawing()). Verarbeitet Zeilenumbrüche in den Formen Chr(13)+Chr(10) und Chr(13).
Parameter:
hdc.l = Device Context mit Font-Infos
*stringAD = Adresse der Null-terminierten Strings, deren Größe ermittelt werden soll
*metrics.SIZE = Adresse der SIZE-Variable, in welcher die Stringröße gespeichert werden soll
[optional] *string_memory = Adresse des Speichers, wo alle gefilterten Zeilen des Strings abgelegt werden
[optional] memsize.l = Größe des String-Ablage-Speichers
Rückgabewert
Die Funktion gibt die Anzahl der Zeilen im zu berechnenden String zurück.
Die Stringablage ist dazu da, alle Zeilen in einer Auslese-freundlichen Form dem Benutzer zu übergeben. Alle Zeilen sind als mit PeekS() leicht lesbaren Strings abgespeichert. In Kombination mit den Pixelgrößen und der per GetTextMetrics_() ermittelten Zeilenhöhe kann so der Text unkompliziert mehrzeilig auf dem Bildschirm ausgegeben werden
Die Größe der String-Ablage kann ganz einfach errechnet werden.
Bei durchgängig 2-Zeichen-Zeilenumbruch:
Bei durchgängig 1-Zeichen-Zeilenumbruch:
Hat bisher allen meinen Test standgehalten, würde gerne wissen, ob bei euch Fehler auftreten und wenn ja, welche?
Gibt die Größe und Breite eines Strings mit vorher festgelegten Font (DrawingFont()) in Pixeln auf einem DC zurück (StartDrawing()). Verarbeitet Zeilenumbrüche in den Formen Chr(13)+Chr(10) und Chr(13).
Parameter:
hdc.l = Device Context mit Font-Infos
*stringAD = Adresse der Null-terminierten Strings, deren Größe ermittelt werden soll
*metrics.SIZE = Adresse der SIZE-Variable, in welcher die Stringröße gespeichert werden soll
[optional] *string_memory = Adresse des Speichers, wo alle gefilterten Zeilen des Strings abgelegt werden
[optional] memsize.l = Größe des String-Ablage-Speichers
Rückgabewert
Die Funktion gibt die Anzahl der Zeilen im zu berechnenden String zurück.
Die Stringablage ist dazu da, alle Zeilen in einer Auslese-freundlichen Form dem Benutzer zu übergeben. Alle Zeilen sind als mit PeekS() leicht lesbaren Strings abgespeichert. In Kombination mit den Pixelgrößen und der per GetTextMetrics_() ermittelten Zeilenhöhe kann so der Text unkompliziert mehrzeilig auf dem Bildschirm ausgegeben werden
Die Größe der String-Ablage kann ganz einfach errechnet werden.
Bei durchgängig 2-Zeichen-Zeilenumbruch:
Code: Alles auswählen
Größe = Textlänge - Zeilen
Code: Alles auswählen
Größe = Textlänge + 1
Code: Alles auswählen
Procedure GetStringMetricsOnDC(hdc.l, *stringAD, *metrics.SIZE, *string_memory=-1, memsize.l=0);optionaler parameter: die gefilterten strings in einem speicher ablegen
Protected checkstring$, checkstring_len.l, c.c, chars_in_string.l, next_char.c, mempos.l
Protected longest_string$, longest_len.l, string_found.b
Protected new_string$, new_len.l, new_metrics.SIZE, breaks_found.l
Protected *proofAD, *stringstartAD
;berechnung des benötigten speichers:
;anzahl zeichen + zeilenumbrüche * 3 (für return, line feed und für jeden string die 0-terminierung)
If hdc <> 0 And *stringAD <> 0 And *metrics <> 0
;/kram zurücksetzen
longest_len = -1
longest_string$ = ""
*proofAD = *stringAD
*stringstartAD = *proofAD
mempos = 0
;/string nach längstem string durchsuchen
Repeat
;char einlesen
c = PeekC(*proofAD)
Debug "c=" + Str(c)
;/zeilenende ("return") gefunden
If c = 13; return entdeckt
;string extrahieren (wir haben die startposition vorher zwischengespeichert)
new_string$ = PeekS(*stringstartAD, chars_in_string)
new_len = chars_in_string
GetTextExtentPoint32_(hdc, @new_string$, new_len, @new_metrics);metrics holen
;/string zwischenspeichern
If *string_memory <> -1
Debug "memory overflow: " + Str(mempos + new_len)
If mempos + new_len <= memsize ;wenn der string den speicher nicht überschreitet
Debug "stored a string @ " + Str(*stringstartAD)
CopyMemory(*stringstartAD, *string_memory + mempos, new_len)
mempos + new_len + 1
EndIf
EndIf
;/vergleichen
;prüfen, ob länge höher als die bisherige, größste länge
If new_metrics\cx > *metrics\cx
Debug "#RECORD!!!"
longest_string$ = new_string$
longest_len = new_len
*metrics\cx = new_metrics\cx
*metrics\cy = new_metrics\cy
EndIf
breaks_found + 1
string_found = #True;"string gefunden" setzen
Debug "new_string$=" + new_string$
Debug "new_len=" + Str(new_len)
Debug "new_metrics\cx=" + Str(new_metrics\cx)
Debug "new_metrics\cy=" + Str(new_metrics\cy)
;-nächstes zeichen analysieren
next_char = PeekC(*proofAD+1)
If next_char = 10;wenn ein line fedd mit angehängt wurde, müssen wir dieses mit in die neue strinposition einrechnen
Debug "line feed (10), next line"
*proofAD = *stringstartAD + chars_in_string + 2;adresse auf nächsten string setzen
*stringstartAD = *proofAD;start des strings setzen
ElseIf next_char = 0;stringende entdeckt, vorgang abbrechen
Debug "string end"
Break
Else;kein linefeed, normal weitergehen im string
Debug "no line feed (!= 10), next line"
*proofAD = *stringstartAD + chars_in_string + 1;adresse auf nächsten string setzen
*stringstartAD = *proofAD ;start des strings setzen
EndIf
;chars im string zurücksetzen
chars_in_string = 0
;/STRING-ENDE
ElseIf c = 0;stringende entdeckt, vorgang abbrechen
;letzter string ohne return/linefeed
new_string$ = PeekS(*stringstartAD, chars_in_string+1)
new_len = chars_in_string
GetTextExtentPoint32_(hdc, @new_string$, new_len, @new_metrics);metrics holen
;/string zwischenspeichern
If *string_memory <> -1
Debug "memory overflow: " + Str(mempos + new_len)
If mempos + new_len <= memsize ;wenn der string den speicher nicht überschreitet
Debug "stored a string @ " + Str(*stringstartAD)
CopyMemory(*stringstartAD, *string_memory + mempos, new_len)
PokeC(*string_memory + mempos + new_len + 1, 0);<-string-ende poken
EndIf
EndIf
;/string zwischenspeichern
;prüfen, ob länge höher als die bisherige, größste länge
If new_metrics\cx > *metrics\cx
longest_string$ = new_string$
longest_len = new_len
*metrics\cx = new_metrics\cx
*metrics\cy = new_metrics\cy
EndIf
Debug "new_string$=" + new_string$
Debug "new_len=" + Str(new_len)
chars_in_string = 0
string_found = #True;"string gefunden" setzen
Break
Else
chars_in_string + 1
*proofAD + 1
EndIf
Debug "----------------------"
ForEver
;/string zurückgeben
If string_found = #True
;wir müssen nur noch die metrics in den vom benutzer angegebenen pointer kopieren und die höhe multiplizieren
*metrics\cy * (breaks_found+1);+1 wegen z.b. der einzelnen zeile die auch ohne umbruch da sein muss (sonst wäre höhe=0)
ProcedureReturn breaks_found + 1
Else
*metrics\cx = 0
*metrics\cy = 0
ProcedureReturn 0
EndIf
Else
*metrics\cx = 0
*metrics\cy = 0
ProcedureReturn 0
EndIf
EndProcedure