Gibt es einen Befehl mit dem man die Breite eines Strings (Schrift = Arial, Größe Variabel) ermitteln kann?
Wenn nicht würde ich auch eine Funktion schreiben, um diese zu errechnen, aber ich finde keine Werte mit denen ich die Breite der einzelnen Buchstaben anhand der Schriftgröße ermitteln kann.
In einem PHP-Forum habe ich etwas gefunden, aber demnach wären die Buchstaben "a,b,c,d,e,g,o, usw." gleich breit. Wenn ich aber "aaaaaaaaaa und darunter "cccccccccc" Schreibe (in Arial), dann ist die Zeile mit dem 10 x c deutlich kürzer als die Zeile mit den 10 x a. Somit können die Werte aus dem PHP-Forum nicht stimmen und etwas anderes finde ich nicht.
Irgendwelche Ideen?
Stringbreite in Pixel ermitteln
Moderator: jNizM
Re: Stringbreite in Pixel ermitteln
Danke.
Da ich meine Funktion später auch ohne GDI+ nutzen will bin ich gerade dabei die Breiten der einzelnen Buchstaben (bzw. das Verhältnis zur Höhe) per GDI+ zu ermitteln.
Diese Werte kann ich dann später in meiner Funktion nutzen, so dass ich dafür dann kein GDI+ mehr benötige.
Da ich meine Funktion später auch ohne GDI+ nutzen will bin ich gerade dabei die Breiten der einzelnen Buchstaben (bzw. das Verhältnis zur Höhe) per GDI+ zu ermitteln.
Diese Werte kann ich dann später in meiner Funktion nutzen, so dass ich dafür dann kein GDI+ mehr benötige.
Re: Stringbreite in Pixel ermitteln
Solange es um die Darstellung in einem GUI geht, hilft die Holzfällermethode:
Code: Select all
#NoEnv
Gui, Font, , Arial
Gui, Add, Text, w150 h20, "aaaaaaaaaa"
Gui, Add, Text, w150 h20, "cccccccccc"
Gui, Add, Text, w150 h20, "WWWWWWWWWW"
Gui, Add, Text, ym wp hp, % StrWidth("aaaaaaaaaa", "", "Arial")
Gui, Add, Text, wp hp, % StrWidth("cccccccccc", "", "Arial")
Gui, Add, Text, wp hp, % StrWidth("WWWWWWWWWW", "", "Arial")
Gui, Show, , String Width
Return
GuiClose:
ExitApp
StrWidth(Str, FontOptions, FontName) {
Gui, StrWidthDummyGUI:Font, %FontOptions%, %FontName%
Gui, StrWidthDummyGUI:Add, Text, hwndHTX, %Str%
GuiControlGet, S, StrWidthDummyGUI:Pos, %HTX%
Gui, StrWidthDummyGUI:Destroy
Return SW
}
Re: Stringbreite in Pixel ermitteln
Vielen Dank, aber in dem Beispiel sind "a" und "c" identisch.
Wenn ich das nun aber in OpenOffice eingebe sind die 10 x "a" länger als die 10 x "c"
Mit GDI+ komme ich auch nur auf falsche Ergebnisse.
Zwar ist da "a" = "b" und "c" ist kleiner als "a" (soweit alles richtig), aber da ist "1" = "a" obwohl 10 x "1" sogar noch schmäler sind als 10 x "c".
Hier ist mein provisorisch zusammen gebasteltes Script um die Breite zu ermitteln (die Ergebnisse Kopiere ich dann einfach mit Strg+C aus der MsgBox):
Die ermittelten Werte nutze ich dann hier (auch noch provisorisch):
Muss nun erst mal aufhören, keine Zeit mehr. Vielleicht bekomme ich durch die Auszeit ja auch wieder einen klaren Kopf
Wenn ich das nun aber in OpenOffice eingebe sind die 10 x "a" länger als die 10 x "c"
Mit GDI+ komme ich auch nur auf falsche Ergebnisse.
Zwar ist da "a" = "b" und "c" ist kleiner als "a" (soweit alles richtig), aber da ist "1" = "a" obwohl 10 x "1" sogar noch schmäler sind als 10 x "c".
Hier ist mein provisorisch zusammen gebasteltes Script um die Breite zu ermitteln (die Ergebnisse Kopiere ich dann einfach mit Strg+C aus der MsgBox):
Code: Select all
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
#Include, Gdip.ahk
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
OnExit, Exit
Width := A_ScreenWidth, Height := A_ScreenHeight
Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
Gui, 1: Show, NA
hwnd1 := WinExist()
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
pBrush := Gdip_BrushCreateSolid(0xaa000000)
Gdip_FillRectangle(G, pBrush, 0, 0, Width, Height)
Gdip_DeleteBrush(pBrush)
Font = Arial
If !hFamily := Gdip_FontFamilyCreate(Font)
{
MsgBox, 48, Font error!, The font you have specified does not exist on the system
ExitApp
}
Gdip_DeleteFontFamily(hFamily)
hFont := Gdip_FontCreate(hFamily, size, "Arial")
hFormat := Gdip_StringFormatCreate(0x4000)
CreateRectF(RectF, x, y, 0, 0)
Options = x10p y30p w80p Centre cbbffffff r4 s120
wert := {}
arial =
Loop, 255
{
text =
char := chr(a_index)
Loop, 10
text .= char
Gdip_TextToGraphics(G, text, Options, Font, Width, Height)
wert[Char] := Gdip_MeasureString(G, text, hFont, hFormat, RectF)
InputVar := wert[Char]
StringSplit, split, InputVar, |
result .= a_index " (" Char ") = " wert[Char] "`n --> " (split3 / 10) / split4 "`n"
arial .= (split3 / 10) / split4 "|"
}
MsgBox % result
MsgBox % arial
UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
TrayTip, GDip Example, Press ESC to Close Example, 10, 1
Return
Esc:: ; Hotkey to exit example
Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp
Return
Die ermittelten Werte nutze ich dann hier (auch noch provisorisch):
Code: Select all
Arial = 0.914669|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026503|0.003571|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026120|0.026834|0.257180|0.321253|0.487919|0.487919|0.764256|0.579900|0.185246|0.302778|0.302778|0.349555|0.511111|0.257180|0.302778|0.257180|0.257180|0.487919|0.487919|0.487919|0.487919|0.487919|0.487919|0.487919|0.487919|0.487919|0.487919|0.257180|0.257180|0.511111|0.511111|0.511111|0.487919|0.868422|0.579900|0.579900|0.625498|0.625498|0.579900|0.533517|0.671882|0.625498|0.257180|0.441536|0.579900|0.487919|0.717479|0.625498|0.671882|0.579900|0.671882|0.625498|0.579900|0.533517|0.625498|0.579900|0.809460|0.579900|0.579900|0.533517|0.257180|0.257180|0.257180|0.415985|0.487919|0.302778|0.487919|0.487919|0.441536|0.487919|0.487919|0.257180|0.487919|0.487919|0.211190|0.211190|0.441536|0.211190|0.717479|0.487919|0.487919|0.487919|0.487919|0.302778|0.441536|0.257180|0.487919|0.441536|0.625498|0.441536|0.441536|0.441536|0.303957|0.242243|0.303957|0.511111|0.026120|0.026120|0.026120|0.470394|0.470394|0.003571|0.026120|0.470394|0.470394|0.349751|0.721256|0.455841|0.470394|0.913137|0.026120|0.026120|0.026120|0.026120|0.204213|0.204213|0.399157|0.399157|0.026120|0.498353|0.909690|0.326388|0.853007|0.349751|0.248257|0.519801|0.026120|0.026120|0.647338|0.026834|0.302778|0.487919|0.487919|0.487919|0.487919|0.242243|0.487919|0.302778|0.637683|0.333831|0.487919|0.511111|0.026120|0.637683|0.484775|0.358595|0.482023|0.302778|0.302778|0.302778|0.504429|0.472196|0.302778|0.302778|0.302778|0.329507|0.487919|0.718265|0.718265|0.718265|0.533517|0.579900|0.579900|0.579900|0.579900|0.579900|0.579900|0.855844|0.625498|0.579900|0.579900|0.579900|0.579900|0.257180|0.257180|0.257180|0.257180|0.625498|0.625498|0.671882|0.671882|0.671882|0.671882|0.671882|0.511111|0.671882|0.625498|0.625498|0.625498|0.625498|0.579900|0.579900|0.533517|0.487919|0.487919|0.487919|0.487919|0.487919|0.487919|0.764256|0.441536|0.487919|0.487919|0.487919|0.487919|0.257180|0.257180|0.257180|0.257180|0.487919|0.487919|0.487919|0.487919|0.487919|0.487919|0.487919|0.482023|0.533517|0.487919|0.487919|0.487919|0.487919|0.441536|0.487919|0.441536
StringSplit , Arial , Arial , |
FontSize := 18
Zeichen1 = 1
Zeichen2 = a
ascii1 := Asc(zeichen1)
ascii2 := Asc(zeichen2)
Breite1 := FontSize * Arial%ascii1%
Breite2 := FontSize * Arial%ascii2%
zeichen1 := "Zeichen1 = " zeichen1 "`nAscii-Code = " Asc(zeichen1) "`nMultiplikator = " Arial%ascii1% "`nBreite = " Breite1
zeichen2 := "Zeichen2 = " zeichen2 "`nAscii-Code = " Asc(zeichen2) "`nMultiplikator = " Arial%ascii2% "`nBreite = " Breite2
MsgBox % "Schriftgröße = " FontSize "`n`n" zeichen1 "`n`n" zeichen2
Re: Stringbreite in Pixel ermitteln
Hmmm, anscheinend funktioniert man Script soweit doch, aber es gibt Probleme mit dem Zeichnen des Textes.
Wenn ich nur 10 x "1" und 10 x "a" zeichnen lasse, dann sind die "Einsen" immer an der gleichen Position der "a"´s, womit natürlichg auch die berechnete Breite identisch ist.
In OpenOffice oder Word sieht das jedoch anders aus, da sind die 10 x "1" kürzer als die 10 x "a".
Woran liegt das? Ein Fehler im GDI+ oder an AHK?
Edit:
Das Beispiel von just me funktioniert doch tadellos. Zwar ist das Ergebnis von "10 x a" das gleiche wie von "10 x c" (und das ist laut OpenOffice / Word nicht der Fall), aber die Darstellung in AHK ist auch gleich (in der MessageBox). Erst wenn ich die Schriftgröße erhöhe weicht die Darstellung voneinander ab, aber dann bekomme ich auch einen anderen Wert.
Das Script zeigt also die tatsächliche Stringlänge an, nur die Darstellung in AHK weicht halt von Textverarbeitungsprogrammen ab.
Das scheint ein Fehler in AHK zu sein.
Nochmals vielen Dank, just me. Dein Script kann ich also doch 1:1 verwenden.
Wenn ich nur 10 x "1" und 10 x "a" zeichnen lasse, dann sind die "Einsen" immer an der gleichen Position der "a"´s, womit natürlichg auch die berechnete Breite identisch ist.
In OpenOffice oder Word sieht das jedoch anders aus, da sind die 10 x "1" kürzer als die 10 x "a".
Woran liegt das? Ein Fehler im GDI+ oder an AHK?
Edit:
Das Beispiel von just me funktioniert doch tadellos. Zwar ist das Ergebnis von "10 x a" das gleiche wie von "10 x c" (und das ist laut OpenOffice / Word nicht der Fall), aber die Darstellung in AHK ist auch gleich (in der MessageBox). Erst wenn ich die Schriftgröße erhöhe weicht die Darstellung voneinander ab, aber dann bekomme ich auch einen anderen Wert.
Das Script zeigt also die tatsächliche Stringlänge an, nur die Darstellung in AHK weicht halt von Textverarbeitungsprogrammen ab.
Das scheint ein Fehler in AHK zu sein.
Nochmals vielen Dank, just me. Dein Script kann ich also doch 1:1 verwenden.
- Seidenweber
- Posts: 17
- Joined: 30 Sep 2013, 11:40
Re: Stringbreite in Pixel ermitteln
Scheinbar haben wir uns so sehr an die WYSIWYG-Darstellung gewöhnt, dass wir das für das Maß aller Dinge halten
So etwas wie die "tatsächliche Stringlänge" gibt es nicht. Es geht nur darum, das spätere Druckergebnis auch schon während der Bearbeitung annähernd so darzustellen, wie es später auf dem Papier aussehen wird.
Und das ist 1) ungenau und 2) je nach Software unterschiedlich. Bei Elementen, die nicht für die Druckausgabe gedacht sind, ist die Ausgabe auf dem Bildschirm naturgemäß anders und ggf auch genauer, als z.B. bei einer Textverarbeitung.
So etwas wie die "tatsächliche Stringlänge" gibt es nicht. Es geht nur darum, das spätere Druckergebnis auch schon während der Bearbeitung annähernd so darzustellen, wie es später auf dem Papier aussehen wird.
Und das ist 1) ungenau und 2) je nach Software unterschiedlich. Bei Elementen, die nicht für die Druckausgabe gedacht sind, ist die Ausgabe auf dem Bildschirm naturgemäß anders und ggf auch genauer, als z.B. bei einer Textverarbeitung.
Questions and answers are related to AHK 1.1.13.01 (x64) & Win 7 pro x64