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