Click here to Skip to main content
15,889,462 members
Articles / Programming Languages / C#

Class for drawing a flat color border

Rate me:
Please Sign up or sign in to vote.
4.82/5 (16 votes)
2 Dec 2006CPOL 91.7K   3.2K   38   22
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. C#
    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. C#
    // 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. C#
    public Color BorderColor
    {
        get { return borderColor; }
        set { borderColor = value; }
    }
  7. Here are the imported functions:
  8. C#
    //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. C#
    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).

    C#
    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. C#
    public Color BorderColor
    {
        get { return borderDrawer.BorderColor; }
        set
        {
            borderDrawer.BorderColor = value;
            Invalidate();
        }
    }

Example

Let's repaint the TextBox border using BorderDrawer:

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerNew way of creating color borders! [modified] Pin
Duke Voldemar25-Nov-10 3:21
Duke Voldemar25-Nov-10 3:21 
GeneralRe: New way of creating color borders! [modified] Pin
Avinash Phadke5-Sep-12 0:56
Avinash Phadke5-Sep-12 0:56 
GeneralTHis does not work on VS 2010 : HERE IS THE FIX Pin
kabamaru23-Nov-10 23:29
kabamaru23-Nov-10 23:29 
GeneralGreat Dude Pin
Member 472154829-Apr-09 21:37
Member 472154829-Apr-09 21:37 
Generalborder color not changing when resize Pin
AmithaRaghu24-Nov-08 19:27
AmithaRaghu24-Nov-08 19:27 
GeneralRe: border color not changing when resize Pin
clevelandraymond18-May-09 15:15
clevelandraymond18-May-09 15:15 
GeneralRe: border color not changing when resize Pin
mutpan29-Jun-09 19:59
mutpan29-Jun-09 19:59 
Generallittle about refresh Pin
dostoyevsky5-Jun-08 8:15
dostoyevsky5-Jun-08 8:15 
GeneralThis does not support changing a FONT Pin
Rmaman21-May-08 0:50
Rmaman21-May-08 0:50 
GeneralGreat Pin
haderspamffs4-Sep-07 18:22
haderspamffs4-Sep-07 18:22 
Generalredraw at runtime don't work with a transparent-color Pin
MarkPhB22-Aug-07 22:01
MarkPhB22-Aug-07 22:01 
GeneralWindows Vista Pin
nbolton11-Jun-07 10:49
nbolton11-Jun-07 10:49 
GeneralRe: Windows Vista Pin
Angelo Cresta13-Aug-07 5:34
professionalAngelo Cresta13-Aug-07 5:34 
GeneralRe: Windows Vista Pin
BillTuer23-Aug-07 4:51
BillTuer23-Aug-07 4:51 
GeneralRe: Windows Vista Pin
Johnny J.7-Nov-07 3:58
professionalJohnny J.7-Nov-07 3:58 
GeneralRe: Windows Vista Pin
Macromullet3-Sep-08 13:14
Macromullet3-Sep-08 13:14 
GeneralDoesn't work on WIndows Server 2003 Pin
ganotganot10-Apr-07 23:00
ganotganot10-Apr-07 23:00 
GeneralRe: Doesn't work on WIndows Server 2003 Pin
Duke Voldemar11-Apr-07 0:34
Duke Voldemar11-Apr-07 0:34 
QuestionRe: Doesn't work on WIndows Server 2003 Pin
Norman-Timo21-May-07 2:21
Norman-Timo21-May-07 2:21 
Hello dear Mr. Voldemar,

I guess it's not a windows2003 specific problem. I have the same problem, that it's not possible to paint custom border colors for textboxes.

First I solved it same way like you, BUT: With Win2003 Server there are ugly 3D-Borders and around them my custom border.

Problem is here same like you are using WinXP: The windows classic theme style!

With that theme style your (and mine too) solution looks ugly, because a inner 3D-border will appear. The solution to set BorderStyle property to "FixedSingle" does not work, because Windows will overpaint the custom border with it's default border.

I don't have any solution seen yet, but perhaps you have any idea about this?

Greetings,
NTR
QuestionDoesn't work if using Opacity on Form Pin
User 50600316-Mar-07 1:03
User 50600316-Mar-07 1:03 
GeneralElegant Pin
Ken Hadden4-Dec-06 10:58
Ken Hadden4-Dec-06 10:58 
GeneralRe: Elegant Pin
Duke Voldemar5-Dec-06 3:54
Duke Voldemar5-Dec-06 3:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.