Microsoft Communities

Welcome to WindowsClient.net | Sign in | Join

Here are some frequently asked questions about Windows Forms and their answers.

Windows Forms FAQs

How do I provide a 1-pixel border in the nonclient area of a Control?

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,
      0x0001 | // 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(); 
}  

Another possible solution that has a design-time element is to use a label with height 1 and FixedSingle Border.

George Shepherd, Syncfusion, and Mark Lewis



Page view counter