Solved

Overriding Textbox with SetStyle breaks it

Posted on 2006-11-19
2
752 Views
Last Modified: 2012-05-05
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
0
Comment
Question by:brotherbill999
2 Comments
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 17979226
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
 

Author Comment

by:brotherbill999
ID: 17981476
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

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you're writing a .NET application to connect to an Access .mdb database and use pre-existing queries that require parameters, you've come to the right place! Let's say the pre-existing query(qryCust) in Access takes a Date as a parameter and l…
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
As a trusted technology advisor to your customers you are likely getting the daily question of, ‘should I put this in the cloud?’ As customer demands for cloud services increases, companies will see a shift from traditional buying patterns to new…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now