Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Class for drawing a flat color border

0.00/5 (No votes)
2 Dec 2006 3  
Use this class in your controls to draw a flat color border in the non-client area.

Sample Image - BorderDrawerClass.png

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

  1. Private fields:
  2. 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
  3. The DrawBorder(ref Message message, int width, int height) method:
  4. // 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);
              }           
         }
    }
  5. The BorderColor property:
  6. public Color BorderColor
    {
        get { return borderColor; }
        set { borderColor = value; }
    }
  7. Here are the imported functions:
  8. //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:

  1. Include in your control class, the BorderDrawer's object:
  2. private BorderDrawer borderDrawer = new BorderDrawer();
  3. Override the WndProc(ref Message m) method.
  4. Call the DrawBorder(...) method in the overridden WndProc(ref Message m) method.
  5. 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);
    }
  6. Add a property that allows to change the border color.
  7. 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!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here