using System;
 using System.Drawing;
 using System.Drawing.Drawing2D;
 using System.Collections;
 using System.ComponentModel;
 using System.Windows.Forms;

 namespace StrangeControls
 {

 // Объявляется класс – наследник базового класса Form.
 // Наша форма, конечно же, основывается на обычной классической
 // прямоугольной, масштабируемой форме.
 // Прежде всего это означает, что у нее имеется свойство Size,
 // значения которого используются для определения размеров
 // составляющих нашу форму элементов.
 // Наша форма состоит из двух элементов:
 // прямоугольника-заголовка
 // (здесь должны размещаться основные элементы управления формы);
 // эллипсовидной клиентской области с голубой каемочкой.    

 public class RoundForm : System.Windows.Forms.Form
 {
 private System.ComponentModel.Container components = null;
 // Объект headSize используется для управления размерами формы.
 private Size headSize;
 // bw – (border width) это переменная,
 // сохраняющая метрические характеристики рамки.
 // В дальнейшем это значение используется для определения 
 // конфигурации нашей формы.
 int bw;

 // Ничем не примечательный конструктор...
 public RoundForm()
 {		
 	InitializeComponent();
 }

 #region Windows Form Designer generated code

 // Required method for Designer support – do not modify
 // the contents of this method with the code editor.

 private void InitializeComponent()
 {
 // 
 // RoundForm
 // 
 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
 this.ClientSize = new System.Drawing.Size(292, 273);
 this.Cursor = System.Windows.Forms.Cursors.Cross;
 this.MinimumSize = new System.Drawing.Size(100, 100);
 this.Name = "RoundForm";
 this.Text = "RoundForm";
 this.Resize += new System.EventHandler(this.RoundForm_Resize);
 }
 #endregion

 protected override void Dispose( bool disposing )
 {
  if( disposing )
  {
  if(components != null)
   {
    components.Dispose();
   }
  }
 	base.Dispose( disposing );
 }

 // Обработчик события, связанного с изменением формы окна, обеспечивает
 // вызов метода, в котором определяются основные характеристики
 // составляющих формы.
 private void RoundForm_Resize(object sender, System.EventArgs e)
 {
 SetSize();
 }

 // Код, определяюший габариты ФОРМЫ – весь здесь...
 // Это определение метрических характеристик ФОРМЫ. 
 protected void SetSize()
 {
  // Всего ничего...
  // На основе соответствующей "классической" формы
  // определяются размеры прямоугольной составляющей (заголовка формы).
  int w = this.Size.Width; 
  bw = (int)((w – this.ClientSize.Width)/2);
  int h = this.Size.Height;
  int bh = h – this.ClientSize.Height – bw;
  headSize = new Size(w,bh);		
 }

 // В рамках переопределенной виртуальной функции...
 protected override void OnPaint(PaintEventArgs e)
 {
 // Определяем габариты формы.
 SetSize();
 // Получаем ссылку на графический контекст.
 Graphics gr = this.CreateGraphics(); 
 // Карандаш для отрисовки каемочки.
 Pen pen = new Pen(SystemColors.Desktop,bw);
 // Объект, поддерживающий контуры формы.
 GraphicsPath gp = new GraphicsPath();
 // Контуры формы образуются прямоугольником
 //(его характеристики совпадают с заголовком формы).
 // класс GraphicsPath не имеет метода, который позволял
 // бы непосредственно подсоединять прямоугольные области.
 // Поэтому структура Rectangle предварительно определяется.
 // С эллипсом проще. Он подсоединяется "на лету",
 // без предварительного определения.
 Rectangle rect = new Rectangle(0,0,headSize.Width,headSize.Height);
 gp.AddRectangle(rect);
 gp.AddEllipse(bw,
               headSize.Height,
               this.ClientSize.Width,
               this.ClientSize.Height);
 // Сформировали объект, поддерживающий контуры формы.
 // И на его основе создаем объект, который описывает внутреннюю часть
 // графической формы.
 // В нашем случае она состоит из прямоугольника и эллипса.  
 Region reg = new Region(gp);
 // У любой формы имеется свойство Region.
 // У нашей формы – оно прекрасно. 
 this.Region = reg;
 // Рисуем каемочку...
 gr.DrawEllipse(pen,0,0,this.ClientSize.Width,this.ClientSize.Height);
 // Освобождаем занятые ресурсы.
 gr.Dispose();
 }
 }
 }

Листинг 17.4.
Закрыть окно