Wie man den genauen Wortlaut Margen verwendet TextRenderer
System.Windows.Forms.TextRenderer.DrawText
- Methode rendert formatierten text mit oder ohne Links und rechts Polsterung je nach dem Wert der flags
parameter:
TextFormatFlags.NoPadding
- passt das text-fest in der bounding-box,TextFormatFlags.GlyphOverhangPadding
- fügt einige Links und rechts Ränder,TextFormatFlags.LeftAndRightPadding
- fügt noch größere Margen.
Nun, meine Frage ist wie bekomme ich die genaue Höhe der Polsterung (Links und rechts) Hinzugefügt von DrawText
auf den text für ein bestimmtes device context, string, schriftart etc?
Ich habe gegraben in .NET 4 mit .NET Reflector und festgestellt, dass die TextRenderer-berechnet "überhang " Auffüllen", das ist 1/6 der schriftart, die Höhe und multipliziert dann diesen Wert zur Berechnung des linken und rechten Ränder mittels dieser Koeffizienten:
- Links 1.0, rechts 1,5 für
TextFormatFlags.GlyphOverhangPadding
, - Links 2.0, rechts 2,5 für
TextFormatFlags.LeftAndRightPadding
.
Die resultierenden Werte sind gerundet und an den DrawTextExA
oder DrawTextExW
native API-Funktionen. Es ist schwierig herzustellen dieser Prozess, weil die font-Höhe stammt nicht von System.Drawing.Font
aber von System.Windows.Forms.Internal.WindowsFont
und diese Klassen zurück, andere Werte für die gleiche schriftart. Und eine Menge von anderen internen BCL-Klassen aus der System.Windows.Forms.Internal
namespace beteiligt sind. Die Dekompilierung, alle von Ihnen und wiederverwenden, Ihren code in meine app ist keine option, denn das würde eine ernsthafte .NET-Implementierung der Abhängigkeit. Das ist, warum ich muss wissen, wenn es eine öffentliche API-in WinForms oder zumindest die Windows-Funktionen kann ich verwenden, um die Werte der linken und rechten Ränder.
Hinweis: ich habe versucht, zu TextRenderer.MeasureText
mit und ohne Polsterung und die Ergebnisse vergleichen, aber das gab mir nur die Summe des linken und rechten Randes, und ich muss Sie separat.
Hinweis 2: In Fall, dass Sie Fragen, warum brauche ich das: ich will zeichnen Sie eine Zeichenfolge mit mehreren Schriftarten/- Farben. Das umfasst das aufrufen DrawText
einmal für alle einheitlich formatiert substring mit NoPadding
option (so dass der text nicht mehr zu verbreiten) aber ich möchte auch hinzufügen, manuell normal GlyphOverhangPadding
ganz am Anfang und ganz am Ende die ganzen multi-format-text.
- +1 für die umfassende Analyse :-). Ich hatte auch dieses problem und die Links-Polsterung Werte, die Sie eingeatmet gelöst es für mich - danke.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Wert, den Sie brauchen für die Berechnung der linken und rechten Ränder ist TEXTMETRIC.tmHeight, was möglich ist, um mit Win32-API.
Allerdings fand ich, dass tmHeight ist nur eine Zeile Höhe der Schrift in Pixeln, so dass diese drei Ansätze geben Sie den gleichen Wert haben (Sie verwenden können, je nachdem, was du wie in deinem code):
Erhalten den linken und rechten Rändern, verwenden wir den gleichen code wie TextRenderer-nicht unter der Haube:
Jetzt können Sie leicht überprüfen, ob
Nur der Hinweis:
Ich brauchte, um dieses problem zu lösen, um zur Umsetzung der "Suche Markieren" - feature in einem ListView-based control verwendet GDI-text-rendering:
Funktioniert wie ein Charme 🙂
Diese Antwort ist ein Auszug von hier - http://www.techyv.com/questions/how-get-exact-text-margins-used-textrenderer#comment-35164
Wenn Sie jemals wollte ein Label oder eine TextBox in Windows Forms führt, dass ein wenig mehr wie auf der web, dann haben Sie wahrscheinlich herausgefunden, dass es keine intuitive Art und Weise zu machen, ein Label oder TextBox automatisch seine Höhe passt der text, den es enthält. Während es möglicherweise nicht intuitiv, es ist definitiv nicht unmöglich.
In diesem Beispiel verwende ich ein Textfeld (Sie könnte genauso gut verwenden ein Label), die angedockt an die Spitze der form.Um es zu verwenden, fügen Sie aTextBox genannt MyTextBox auf das Formular, und legen Dock auf DockStyle.Top. Verdrahten Sie die Resize-Ereignis der TextBox zu diesem event-handler.
Wenn Sie wollen, um die Größe des ein Label oder eine TextBox, die nicht angedockt ist (zum Beispiel einen, der in einem FlowLayoutPanel oder andere Fenster, oder einfach nur auf dem Formular platziert), dann können Sie die Form, die Größe selbst statt, und ändern Sie die Eigenschaften des Steuerelements direkt.
Das mag (sehr) grob, aber dies ist die einzige native Implementierung, die ich denken kann:
DrawText
zieht, um eineIDeviceContext
implementiert durchGraphics
. Nun, wir können den Vorteil, dass mit dem folgenden code:Mit der neuen
Bitmap
Sie gehen können, pixel für pixel, und zählen Sie Sie durch eine Bedingung.Wieder, diese Methode ist sehr primitiv und verschwenderisch, aber zumindest ist es die native....
Dies ist nicht getestet, aber basierend auf folgenden Quellen:
http://msdn.microsoft.com/en-us/library/4ftkekek.aspx
http://msdn.microsoft.com/en-us/library/system.drawing.idevicecontext.aspx
http://msdn.microsoft.com/en-us/library/system.drawing.graphics.aspx
http://www.pcreview.co.uk/forums/graphics-bitmap-t1399954.html
Habe ich etwas ähnliches gemacht vor ein paar Jahren, zur Markierung der Suchergebnisse (Suche nach Muster erscheint in Fettdruck, etc.). Meine Implementierung war in DevExpress, so könnte der code nicht relevant sein. Wenn Sie denken, dass es ich es kopieren können, müssen Sie nur finden, dass die Implementierung.
In
System.Windows.Forms
die Klasse zu verwenden, wäreGraphics
. Es hat eine MeasureCharacterRanges() Methode akzeptiertStringFormat
(start mit GenericTypographic und gehen von dort aus). Es ist viel besser geeignet als TextRenderer für die Anzeige eine vollständige Zeichenfolge durch Verkettung Teile mit verschiedenen Stilen, Schriftarten oder Bürsten.Du gegangen bist Weg, weiter als mich mit der eigentlichen Polsterung Messen. DevExpress Steuerungen, gab Sie den text umschließendes Rechteck, mit zu beginnen, also war das für mich getan.
Hier ein Artikel von Pierre Arnaud, der kam für mich in Google, berührt auf diesem Gebiet. Leider sind die GDI+ "blutigen details" - link, es ist gebrochen.
Jubel
Jonno
Das Update ist, was zu berechnen
MeasureText
wird hinzufügen:Berechnen wir die Breite der Raum und die Breite der beiden Räume. Beide haben die zusätzliche Breite Hinzugefügt, so können wir extrapolieren die extra Breite, der Hinzugefügt wird. Die Breite Hinzugefügt scheinbar ist immer das gleiche, so dass die Subtraktion
extra
von jeder Breite zurückgegebenMeasureText
gibt die erwarteten Ergebnisse.