Как нарисовать подсветку за Richtextbox

#vb.net #richtextbox

#vb.net #richtextbox

Вопрос:

Используя этот код, он рисует подсветку на тексте, что делает текст каким-то образом размытым?

 Public Class HighlightableRTB
Inherits RichTextBox

Private LineHeight As Integer = 15

Public Sub New()
    HighlightColor = Color.Yellow
End Sub

<Category("Custom"), Description("Specifies the highlight color.")>
Public Property HighlightColor As Color

Protected Overrides Sub OnSelectionChanged(ByVal e As EventArgs)
    MyBase.OnSelectionChanged(e)
    Me.Invalidate()
End Sub

Private Const WM_PAINT As Integer = 15

Protected Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = WM_PAINT Then
        Dim selectLength = Me.SelectionLength
        Dim selectStart = Me.SelectionStart
        Me.Invalidate()
        MyBase.WndProc(m)
        If selectLength > 0 Then Return

        Using g As Graphics = Graphics.FromHwnd(Me.Handle)
            Dim b As Brush = New SolidBrush(Color.FromArgb(50, HighlightColor))
            Dim line = Me.GetLineFromCharIndex(selectStart)
            Dim loc = Me.GetPositionFromCharIndex(Me.GetFirstCharIndexFromLine(line))
            g.FillRectangle(b, New Rectangle(loc, New Size(Me.Width, LineHeight)))
        End Using
    Else
        MyBase.WndProc(m)
    End If
End Sub
End Class
  

Как можно нарисовать прямоугольную подсветку за текстом richtextbox?

Ответ №1:

Как вы уже догадались, текст на самом деле не «размытый»… это желтый прямоугольник, который закрашен поверх него, что придает ему такой вид.

Это будет нелегко. На самом деле, у меня есть решение, но это не то, что я бы рекомендовал … если бы мне было что еще сказать. Но я этого не сделал, поэтому вот один из способов решения этой проблемы:

Вы можете нарисовать текст … поверх текста. Это не удаляет текст, который уже существует… но закрашивает ее. Если ваши координаты немного неточны, это будет выглядеть дерьмово, но если вы получите точное правильное место, это сработает как шарм. Ужасный, хакерский шарм:

 Using g As Graphics = Graphics.FromHwnd(Me.Handle)
    Dim b As Brush = New SolidBrush(Color.FromArgb(50, HighlightColor))
    Dim line = Me.GetLineFromCharIndex(Me.SelectionStart)
    Dim loc = Me.GetPositionFromCharIndex(Me.GetFirstCharIndexFromLine(line))
    g.FillRectangle(b, New Rectangle(loc, New Size(Me.Width, LineHeight)))
    TextRenderer.DrawText(g, Me.Text, Font, New Point(-2, 1), ForeColor) ' this is the important line!
End Using
  

Хакерская прелесть!

Тем не менее, это 100% хак, и я очень надеюсь, что кто-нибудь более здравомыслящий, чем я, вмешается. Позиция, которую я написал (-2, 1), должна сработать, но если почему-то это не сработает, вы можете избавиться от прозрачности, чтобы скрыть свой позор, заменив ее Color.FromArgb(50, HighlightColor) на Color.FromArgb(255, HighlightColor) . Это будет не так очевидно, поскольку текст раскроет этот грязный трюк только тогда, когда кто-то его выберет (попробуйте!).

Получайте удовольствие!

Комментарии:

1. Подсветка не соответствовала текущей строке курсора. Это рисует все. Кроме того, в нарисованный текст не вставляется фактический текст, который должен быть выделен при прокрутке вниз. Что я на самом деле хочу, так это тот тип, который есть в Notepad , вы знаете, он рисует фон текущей строки, в которой находится курсор, в то время как текст все еще остается четким. Так что, если есть какие-либо другие средства для достижения этого, я буду признателен.

2. Это потому, что я изменил эту часть: New Size(Me.Width, Me.Lines.Count * LineHeight) чтобы каждая строка была желтой. Ваш исходный код рисовал только первую строку. Я обновляю фрагмент кода некоторыми новыми значениями и изображением.

3. Это устранило вашу проблему? Если вы исправили другой способ, вы также можете опубликовать свой собственный ответ, поскольку это может быть полезно будущему пользователю, у которого возникнет подобная проблема.