2017-11-02 4 views
3

Die Dokumentation [ here ] sagt, wenn wir die DT_CALCRECT Flag verwenden, dann würde unten getan: Wie wird das 'DrawText' Rechteck genau in den Text eingefügt?

Bestimmt die Breite und Höhe des Rechtecks ​​

. Wenn mehrere Textzeilen vorhanden sind, verwendet DrawText die Breite des Rechtecks ​​ , auf die der Parameter pRect zeigt, und erweitert die Basis des Rechtecks ​​ , um die letzte Textzeile zu begrenzen. Wenn es nur eine Zeile Text gibt, ändert DrawText die rechte Seite des Rechtecks, so dass das letzte Zeichen in der Zeile begrenzt. In beiden Fällen gibt DrawText die Höhe des formatierten Texts zurück, zeichnet jedoch den Text nicht.

Es ist aus der Beschreibung klar, dass DT_CALCRECT wird die DrawTextnicht machen, den Inhalt zu ziehen, so dass ich so etwas wie

DrawTextExA(hdc, fromsqlite->descrip, -1, &rect, DT_CALCRECT, NULL); 
// On debugging, I can see that rect is being modified in the above step. 
if (DrawTextExA(hdc, fromsqlite->descrip, -1, &rect, 
      DT_LEFT | DT_EDITCONTROL | DT_WORDBREAK, NULL) == 0) { 
MessageBox(NULL, L"DrawText failed", NULL, MB_OK); 
} 

Das Problem ist jetzt soll, dass die Breite des Rechtecks ​​tun sollte repariert sein. Also möchte ich nur die Basis des Rechtecks ​​rect erweitert werden. In meinem Fall wird jedoch fromsqlite->descrip, die aus einer sqlite Datenbank abgerufen wird immer als single-line Text betrachtet.

Jede Hilfe wird geschätzt.

Antwort

4

DT_WORDBREAK sollte hinzugefügt werden, um die einzelne Textzeile zu unterbrechen.

DT_CALCRECT sollte mit dem endgültigen Format kombiniert werden, um das Rechteck zu erhalten.

Dokumentation: DrawText function (GDI-Funktion)

DT_WORDBREAK
Breaks Worte. Zeilen werden automatisch zwischen Wörtern unterbrochen, wenn ein Wort über die Kante des Rechtecks ​​hinausgeht, das durch den LpRect-Parameter angegeben wurde. Eine Wagenrücklaufzeilen-Zuführsequenz unterbricht auch die Zeile .

Wenn dies nicht angegeben ist, erfolgt die Ausgabe in einer Zeile.

Beispiel:

RECT rc={ 0, 0, 200, 0 }; 
const wchar_t* text = L"word1 word2 word3 word4 word5"; 
UINT format = DT_LEFT | DT_TOP | DT_EDITCONTROL | DT_WORDBREAK; 
DrawText(hdc, text, -1, &rc, format | DT_CALCRECT); 
DrawText(hdc, text, -1, &rc, format); 

Leistung vergleichbar wäre, die folgenden (je nach Schriftgröße)

word1 word2 word3
Word4 word5

Ist DT_EDITCONTROL notwendig?

Betrachten Sie dieses Beispiel:

text = L"SingleLinexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 
format = DT_LEFT | DT_TOP | DT_WORDBREAK; 
DrawText(hdc, text, -1, &rc, format | DT_CALCRECT); 
DrawText(hdc, text, -1, &rc, format); 

Dieses Mal „Wort“, dass Rechtecks ​​längere Breite sein könnte, Linie nicht brechen wird, wird der Text auf der rechten Seite überschwappen.

Sie können das Format mit DT_EDITCONTROL oder anderen Flags wie DT_WORD_ELLIPSIS kombinieren, um sicherzustellen, dass auf der rechten Seite kein Überlauf vorhanden ist.

DrawTextEx verwendet die gleichen DT_XXXX Flags.

Seitliche Anmerkung: Wenn Ihr Text UTF-8 ist, können Sie mit MultiByteToWideChar in UTF-16 konvertieren, anstatt DrawTextA, die ANSI-Eingabe erwartet.

+0

Prost Kumpel! Ich untersuche das. 'DrawTextA' ist hier beabsichtigt, da ich mich streng mit ANSI-Eingaben beschäftige. – sjsam

+0

Nun, das hat funktioniert! Eine schöne Technik in der Tat. Aber ich habe nicht das 'DT_EDITCONTROL'-Flag verwendet, das ich hier nicht brauche. – sjsam

+2

@sjsam Sie verwenden' DT_EDITCONTROL' in Ihrem Beispiel. Wie diese Antwort korrekt zeigt, müssen Sie beim ersten Aufruf von 'DrawText' die gleichen Flags verwenden wie beim zweiten Aufruf von' DrawText', andernfalls ist das berechnete Rechteck falsch. – zett42

Verwandte Themen