
Introduction
Standard Windows Forms controls don't allow you to change border colors. I introduce here the BorderDrawer
class which contains a simple code that helps to solve this problem. You may use this class for creating your custom controls.
BorderDrawer Class
- Private fields:
private Color borderColor = Color.Black; private static int WM_NCPAINT = 0x0085; private static int WM_ERASEBKGND = 0x0014; private static int WM_PAINT = 0x000F;
- The
DrawBorder(ref Message message, int width, int height)
method:
public void DrawBorder(ref Message message, int width, int height)
{
if (message.Msg == WM_NCPAINT || message.Msg == WM_ERASEBKGND ||
message.Msg == WM_PAINT)
{
IntPtr hdc = GetDCEx(message.HWnd, (IntPtr)1, 1 | 0x0020);
if (hdc != IntPtr.Zero)
{
Graphics graphics = Graphics.FromHdc(hdc);
Rectangle rectangle = new Rectangle(0, 0, width, height);
ControlPaint.DrawBorder(graphics, rectangle,
borderColor, ButtonBorderStyle.Solid);
message.Result = (IntPtr)1;
ReleaseDC(message.HWnd, hdc);
}
}
}
- The
BorderColor
property:
public Color BorderColor
{
get { return borderColor; }
set { borderColor = value; }
}
- Here are the imported functions:
[DllImport("user32.dll")]
static extern IntPtr GetDCEx(IntPtr hwnd, IntPtr hrgnclip, uint fdwOptions);
[DllImport("user32.dll")]
static extern int ReleaseDC(IntPtr hwnd, IntPtr hDC);
Using the code
To get results, you only need to do four things:
- Include in your control class, the
BorderDrawer
's object:
private BorderDrawer borderDrawer = new BorderDrawer();
- Override the
WndProc(ref Message m)
method.
- Call the
DrawBorder(...)
method in the overridden WndProc(ref Message m)
method.
Note that calling DrawBorder(...)
should be after(!) calling base.WndProc(ref m)
.
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
borderDrawer.DrawBorder(ref m, this.Width, this.Height);
}
- Add a property that allows to change the border color.
public Color BorderColor
{
get { return borderDrawer.BorderColor; }
set
{
borderDrawer.BorderColor = value;
Invalidate();
}
}
Example
Let's repaint the TextBox
border using BorderDrawer
:
public class TextBoxWithColorBorder : TextBox
{
private BorderDrawer borderDrawer = new BorderDrawer();
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
borderDrawer.DrawBorder(ref m, this.Width, this.Height);
}
public Color BorderColor
{
get { return borderDrawer.BorderColor; }
set
{
borderDrawer.BorderColor = value;
Invalidate();
}
}
}
Happy coding!