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. |
| Закрыть окно |