You will have to first provide some space in the NC area by setting the WS_BORDER flag in CreateParams and then draw the border yourself by listening to the WM_NCPAINT message in your Control, as follows:
protected override CreateParams CreateParams
{
get
{
System.Windows.Forms.CreateParams cp = base.CreateParams;
if(this.needFlatBorder)
{
cparams.ExStyle &= ~512 /*WS_EX_CLIENTEDGE*/;
cparams.Style &= ~8388608 /*WS_BORDER*/;
cp.Style |= 0x800000; // WS_BORDER
}
}
}
protected override void WndProc(ref Message m)
{
if(m.Msg == 133/*WM_NCPAINT*/)
{
this.DrawFlatNCBorder(ref m);
}
base.WndProc(ref m);
}
private void DrawFlatNCBorder(ref Message msg)
{
IntPtr hRgn1 = (IntPtr) msg.WParam;
// The update region is clipped to the window frame. When wParam is 1, the entire window frame needs to be updated.
IntPtr hdc = NativeMethods.GetDCEx(msg.HWnd, hRgn1, 1/*DCX_WINDOW*/|0x0020/*DCX_PARENTCLIP*/);
if (hdc != IntPtr.Zero)
{
using (Graphics g = Graphics.FromHdc(hdc))
{
Rectangle bounds = new Rectangle(0,0,this.Width,this.Height);
ControlPaint.DrawBorder(g,bounds,this.borderColor,ButtonBorderStyle.Solid);
// create a clipping region for remaining parts to be drawn excluding
// the border we did just drew
bounds.Inflate(-1, -1);
IntPtr hRgn2 = NativeMethods.CreateRectRgn(bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);
if(hRgn2 == (IntPtr)1)
{
// Provide a new clipping region.
msg.WParam = (IntPtr) hRgn2;
}
else
{
// combine with existing clipping region.
NativeMethods.CombineRgn(hRgn1, hRgn1, hRgn2, NativeMethods.RGN_AND);
NativeMethods.DeleteObject(hRgn2);
}
}
msg.Result = (IntPtr) 1;
NativeMethods.ReleaseDC(msg.HWnd, hdc);
}
Invalidate();
}
Share with