Overriding Textbox with SetStyle breaks it

The goal is to build a custom TextBox, which permits drawing a bold box around it, to accentuate the box.
To do this, it is necessary to override the OnPaint event.
The onPaint event only fires if SetStyle is called in the control's constructor.
The problem is that the custom textbox doesn't display the same font, nor does it display the value as design time.
And I don't want to reinvent the wheel by reimplementing the standard textbox drawing of standard text.
If you use the designer to add a standard TextBox and MyTextBox controls, you will see the differences in behavior.
What is necessary, so that OnPaint may be called, but otherwise standard TextBox behavior is used?

Imports System.Windows.Forms
Imports System.Drawing

Public Class MyTextBox
    Inherits TextBox

    Public Sub New()
        MyBase.new()
        SetStyle(ControlStyles.UserPaint, True)  ' enable OnPaint call
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
    End Sub
End Class
brotherbill999Asked:
Who is Participating?
 
Bob LearnedConnect With a Mentor Commented:
Here is an VB.NET 2005 example that overrides the default WndProc to wait for the WM_PAINT message:

Imports System.ComponentModel
Imports System.Runtime.InteropServices

Public Class CustomTextBox : Inherits TextBox

    <Description("Returns a window handler."), _
    DllImport("user32.dll", _
    SetLastError:=True, CharSet:=CharSet.Auto, ExactSpelling:=True, _
    CallingConvention:=CallingConvention.StdCall)> _
    Private Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
    End Function

    <Description("frees a window handler."), _
        DllImport("user32.dll", _
        SetLastError:=True, CharSet:=CharSet.Auto, ExactSpelling:=True, _
        CallingConvention:=CallingConvention.StdCall)> _
    Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
    End Function

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Const WM_PAINT = &HF
        MyBase.WndProc(m)

        If m.Msg = WM_PAINT Then
            Dim hDC As IntPtr = GetWindowDC(Handle)
            Using gdc As Graphics = Graphics.FromHdc(hDC)
                Dim rect As Rectangle = New Rectangle(0, 0, Me.Width, Me.Height)
                Using pen As New Pen(Color.Red, 2)
                    gdc.DrawRectangle(pen, rect)
                    ReleaseDC(Handle, hDC)
                End Using
            End Using

        End If
    End Sub
End Class

Bob
0
 
brotherbill999Author Commented:
Thanks Bob, here's a solution that meets my needs.  The key is overriding WndProc as you indicated.
You certainly have helped me O Learned One.
Here's the working solution that works for me!

Imports System.Windows.Forms
Imports System.Drawing

Public Class MyTextBox
    Inherits TextBox

    ' Draw a thick blue border around the TextBox, using the Parent's Graphics
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Const WM_PAINT As Integer = &HF
        MyBase.WndProc(m)

        If m.Msg = WM_PAINT Then
            Const boldThickness As Integer = 2     ' 2 pixels
            If boldThickness <= 0 Then Exit Sub
            Dim grfx As Graphics = Parent.CreateGraphics
            Dim location As Point = Me.Location
            Dim size As Size = Me.Size
            Dim rect As New Rectangle(location.X, location.Y, size.Width, size.Height)
            rect.Inflate((boldThickness + 1) >> 1, (boldThickness + 1) >> 1)
            If (boldThickness Mod 2) = 1 Then
                rect.Height -= 1
                rect.Width -= 1
            End If
            Dim pen As New Pen(Color.Blue, boldThickness)
            grfx.DrawRectangle(pen, rect)
            grfx.Dispose()
        End If
    End Sub
End Class
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.