Trying to set caret at correct offset: CLOSED
-
This solved my problem: Dim szF As SizeF = gr.MeasureString(Me.Text.Substring(0, iIndex), Me.Font, New SizeF(999, 999), StringFormat.GenericTypographic) I have a control derived from UserControl in which I am trying to implement like a TextBox and I am having trouble setting the caret in the correct text column position. Below is the code to calculate the x offset and move the caret. Simple test: With the text "aBc", when I try to set the caret between 'a' and 'B' (iIndex=1), the caret is displayed almost at the end of the 'B'. MeasureDisplayStringWidth() is test code I found on the internet and does not make any difference than using gr.MeasureString(). SetCaretPos() is the standared Windows API for setting the caret. And for those who wonder why I don't just use a TextBox, this control has all kinds of custom stuff including rotation. I would appreciate any help. Thank you Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) Dim sb As SolidBrush = New SolidBrush(Color.FromArgb(255, 0, 0, 255)) ' Display text e.Graphics.DrawString(Me.Text, me.Font, sb, 0, 0) End Sub Private Sub MoveCaret(ByVal iIndex As Integer) Dim gr As Graphics = Me.CreateGraphics() ' Both of these give the same result. 'Dim szF As SizeF = gr.MeasureString(Me.Text.Substring(0, iIndex), Me.Font) Dim i As Integer = MeasureDisplayStringWidth(gr, Me.Text.Substring(0, iIndex), Me.Font) gr.Dispose() gr = Nothing ' Windows api call MyUtilsLib.WindowsAPI.SetCaretPos(i, 1) End Sub Public Function MeasureDisplayStringWidth(ByVal gr As Graphics, ByVal text As String, ByVal fnt As Font) As Integer If text.Length < 1 Then Return 0 Dim format As System.Drawing.StringFormat = New System.Drawing.StringFormat() Dim rect As System.Drawing.RectangleF = New System.Drawing.RectangleF(0, 0, 1000, 1000) Dim ranges As System.Drawing.CharacterRange() = {New System.Drawing.CharacterRange(0, text.Length)} Dim regions As System.Drawing.Region() = {New System.Drawing.Region()} format.SetMeasurableCharacterRanges(ranges) regions = gr.MeasureCharacterRanges(text, fnt, rect, format) rect = regions(0).GetBounds(gr) Return CInt(rect.Right + 1.0F) End Function