?
Solved

Overriding Textbox with SetStyle breaks it

Posted on 2006-11-19
2
Medium Priority
?
775 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 96

Accepted Solution

by:
Bob Learned earned 2000 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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
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…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses

766 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