Class for drawing a flat color border






4.82/5 (14 votes)
Use this class in your controls to draw a flat color border in the non-client area.
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:
- The
DrawBorder(ref Message message, int width, int height)
method: - The
BorderColor
property: - Here are the imported functions:
private Color borderColor = Color.Black; // default border color is black
private static int WM_NCPAINT = 0x0085; // WM_NCPAINT message
private static int WM_ERASEBKGND = 0x0014; // WM_ERASEBKGND message
private static int WM_PAINT = 0x000F; // WM_PAINT message
// message - a message from control's WndProc(ref Message m) method
// width - controls' width
// height - controls' height
public void DrawBorder(ref Message message, int width, int height)
{
if (message.Msg == WM_NCPAINT || message.Msg == WM_ERASEBKGND ||
message.Msg == WM_PAINT)
{
//get handle to a display device context
IntPtr hdc = GetDCEx(message.HWnd, (IntPtr)1, 1 | 0x0020);
if (hdc != IntPtr.Zero)
{
//get Graphics object from the display device context
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);
}
}
}
public Color BorderColor
{
get { return borderColor; }
set { borderColor = value; }
}
//The GetDCEx function retrieves a handle to a display device context
//(DC) for the client area of a specified window
[DllImport("user32.dll")]
static extern IntPtr GetDCEx(IntPtr hwnd, IntPtr hrgnclip, uint fdwOptions);
//the ReleaseDC function releases a device context (DC)
[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: - Override the
WndProc(ref Message m)
method. - Call the
DrawBorder(...)
method in the overriddenWndProc(ref Message m)
method. - Add a property that allows to change the border color.
private BorderDrawer borderDrawer = new BorderDrawer();
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);
}
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
{
//creating instance of BorderDrawer class
private BorderDrawer borderDrawer = new BorderDrawer();
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
//calling DrawBorder method
borderDrawer.DrawBorder(ref m, this.Width, this.Height);
}
//this property allows control's users change border color
public Color BorderColor
{
get { return borderDrawer.BorderColor; }
set
{
borderDrawer.BorderColor = value;
Invalidate();
}
}
}
Happy coding!