Extending the TextBox
Hi,
I have been trying to extend the text box to add new properties like Border Color, Border Width etc. At design time things look fine, however at runtime, when the focus is set on the text box, the text is displayed in large bold font and the control does not behave properly. It does not process the backspace and other keys.
Following is the code that I wrote. In the constructor, I changed the style to 'User Paint'. I am then overriding the OnPaint method to draw the border and the text.
Public Sub New()
MyBase.New()
Me.SetStyle(ControlStyles.UserPaint, True)
End Sub
Protected Overrides Sub OnPaint(ByVal e As _
System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
'
Call DrawText(e.Graphics)
Call DrawBorder(e.Graphics)
'
End Sub
Private Function DrawBorder(ByVal g As Graphics)
ControlPaint.DrawBorder(g, Me.ClientRectangle, _
BorderColor, BorderWidth, ButtonBorderStyle.Solid, _
BorderColor, BorderWidth, ButtonBorderStyle.Solid, _
BorderColor, BorderWidth, ButtonBorderStyle.Solid, _
BorderColor, BorderWidth, ButtonBorderStyle.Solid)
End Function
Private Function DrawText(ByVal g As Graphics)
Dim objTextRect As Rectangle = Me.ClientRectangle
objTextRect.Inflate(-BorderWidth, -BorderWidth)
g.DrawString(Me.Text, Me.Font, New SolidBrush(Color.Black), BorderWidth, _
BorderWidth)
End Function
could some one pl help or point me to some similar example.
thanks
Philip
Phillip, I just played with your code a bit and couldn't get it to do the right thing. It appears that even when UserPaint and AllPaintingInWMPaint are both set, that Windows still does some drawing for a TextBox. I don't think there will be a way around this.
I'm not sure what your exact app requirements are, but I'd suggest a solution where you set the borderstyle on the TextBox to be a single pixel and then draw a border around the outside of the control.
- mike
Hi,
the border is painted in the "wm_ncpaint" windows event.
subclass the control like this
protected override WndProc(....
{
if (m.Message==wm_ncpaint){ //lookup wm_ncpaint constant in "winuser.h"
Graphics G=this.CreateGraphics();
//draw stuff here
G.Dispose();
}
else
base.WndProc(ref m);
}
NOTE: the code above is just out of my head and may not be 100% correct , but i have done this and it works fine.
anyway read about wm_ncpaint (Windows Message _ Non Client Paint)
//Roger
www.compona.com
Hi, rogeri
I have one comment on your post.
As you said the border is a non-client feature of the text-box and the CreateGraphics()function gives you only the client surface for drawing. As I am doing custom caption form now I read a lot about non-client painting : what you need to do (the only way to obtain the non-client area for drawing) is to import the win32 API GetWindowDc (or GetDCEx) and then
if hDC = GetWindowDC(...)
call Graphics g = Graphics.FromHdc(hDC)
protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
.....................
case 0x0085://WM_NCPAINT
IntPtr hDC = GetWindowDC(this.Handle);
Graphics g = Graphics.FromHdc(hDC);
//as GetWindowDC returns the entire surface of the window +
//client area included, be careful with painting - do some calculations here and then draw
ReleaseDC(this.Handle, hDC);//another win32 API
g.Dispose();
break;
....................
}