Fehler bei Messung der Textgröße (GetTabbedTextExtent)
-
Hallo zusammen,
also, folgendes Szenario:
Ich habe eine mit CreateFontIndirect erstellte Schrift in einen Gerätekontext eingesetzt, um mir anschließend die Abmessungen eines bestimmten Textes ('Hallo') ausgeben zu lassen (natürlich nur testweise
).Der Code dafür, sieht so aus:
#include <windows.h> #include "CString.hpp" #include "Resource.h" INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uiMessage, WPARAM wParam, LPARAM lParam) { using NStr::CString; switch(uiMessage) { case WM_INITDIALOG: SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); break; case WM_SIZE: InvalidateRect(hDlg, NULL, TRUE); break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hDlg, &ps); LOGFONT lfFontData = { 0 }; lstrcpyn(lfFontData.lfFaceName, TEXT("Arial"), LF_FACESIZE); HFONT hfPrev = static_cast<HFONT>(SelectObject(ps.hdc, CreateFontIndirect(&lfFontData))); const TCHAR szOut[] = TEXT("Hallo"); TextOut(ps.hdc, 100, 70, szOut, lstrlen(szOut)); /* ------------------------------------ */ TextOut(ps.hdc, 0, 0, (CString(TEXT("Breite: ")) + CString(static_cast<long>(LOWORD(GetTabbedTextExtent(ps.hdc, szOut, lstrlen(szOut), 0, NULL))))).GetString(), (CString(TEXT("Breite: ")) + CString(static_cast<long>(LOWORD(GetTabbedTextExtent(ps.hdc, szOut, lstrlen(szOut), 0, NULL))))).GetLength()); TextOut(ps.hdc, 0, 30, (CString(TEXT("Höhe: ")) + CString(static_cast<long>(HIWORD(GetTabbedTextExtent(ps.hdc, szOut, lstrlen(szOut), 0, NULL))))).GetString(), (CString(TEXT("Höhe: ")) + CString(static_cast<long>(HIWORD(GetTabbedTextExtent(ps.hdc, szOut, lstrlen(szOut), 0, NULL))))).GetLength()); /* ------------------------------------ */ DeleteObject(SelectObject(ps.hdc, hfPrev)); EndPaint(hDlg, &ps); } break; case WM_CLOSE: case WM_DESTROY: EndDialog(hDlg, 0); break; default: return (FALSE); } return (TRUE); }Vorweg noch ein paar Anmerkungen zum Code:
Die Klasse CString, ist eine von mir geschriebene String-Klasse und ähnelt stark der Klasse std::string/std::wstring, hier wird sie nur verwendet, um eine Zahl in einen String zu verwandeln, da der Konstruktor dieser Klasse für den Datentyp long überladen ist (siehe static_cast im Code). Ich weiß, es gibt zahlreiche andere Möglichkeiten das zu konvertieren, aber das lag in diesem Fall am nächsten
. GetString() arbeitet wie c_str() und GetLength() wie length() - wär häts gedacht
. Vllt gibt es hier und da Möglichkeiten die Performance noch zu verbessern, aber das ist nicht wichtig.So, nun zum Problem:
Die ausgegebenen Werte stimmen in keinster Weise mit den tatsächlichen Abmessungen der Schrift überein
. Als Höhe ermittelt die Funktion 18, überprüft man das jedoch in 'MS-Paint', so kommt man nur auf 12. Ich hab das ganze auch mal mit der Funktion GetTextExtentPoint32 probiert, diese liefert aber das selbe Ergebnis (da ich aber später auch Tabulatoren brauche, muss es eben am Ende GetTabbedTextExtent sein).Hier auch nochmal ein Screenshot, den ich ein bisschen bearbeitet habe, damit die Sache deutlicher wird
http://img136.imageshack.us/my.php?image=screenshotdlgschriftmesiq8.png .Glaube ja, es ist was triviales, aber ich sitze daran nun schon länger - habt ihr ne Idee ?
Schonmal vielen Dank
!PS: Die mit Paint ausgelesene Breite, ist in Ansätzen noch nachvollziehbar und lässt sich vllt auf den Abstand der Buchstaben zueinander, also das character-kerning, zurückführen, aber zu der Höhe fällt mir nichts mehr ein.
-
Nimm statt "Hallo" lieber "gM" zum ausmessen :
http://msdn2.microsoft.com/en-us/library/ms533936.aspx
-
Man muss berücksichtigen, dass hier auchnoch external ladings zur Anwednung kommen. Ich nehme sicherheithalber am liebsten g oder y und einen der großen Umlaute ÄÖÜ.
-
Jupp, danke erstmal!
Also 'gM' hat nichts gebracht. Da kam das gleiche raus. Nach ein bisschen probieren hab ich nun heraus bekommen, dass die 'tiefsten' Buchstaben q, y, g, ... sind (wie Martin schon geschrieben hat
), der 'höchste' ist das Ó . Aber irgendwie lößt das mein Problem nur teilweise. Ich wollte eigentlich die tatsächliche Höhe eines ganz bestimmten Strings ermitteln. Wenn dort eben derartige Zeichen nicht vorhanden sind (wie eben in 'Hallo' oder 'pM' kein Ó vorhanden ist
), ist der String ja auch (in diesem Fall) nicht so hoch. Gibts da Möglichkeiten das zu berechnen ?
-
*push* - Geht das überhaupt (Oder besser: Ist überhaupt klar, was ich meine
) ?