Одной из интереснейших особенностей окон в приложениях .NET является то, что программист может задать им нестандартную форму (например как у Windows Media Player). Это позволяет сделать интерфейс программ более привлекательным, что является важным моментом у различного рода мультимедийных приложений. В этой статье я опишу как задать окнам в приложениях на C# нестандартную форму.
Шаг 1. Создаем в своем любимом графическом редакторе картинку, которая будет выступать формой нашего окна. Не нужную область (область которую мы хотим сделать прозрачной (Background)) обязательно закрашиваем в черный цвет. На основании этого цвета и будет производиться «формовка» окна.

Шаг 2. Создаем в Microsoft Visual Studio .NET новый проект оконной программы (Windows Application Project).
Шаг 3. В свойствах формы устанавливаем свойство FormBorderStyle (стиль рамки окна) в None. В качестве BackgroundImage указываем изображение, которое создали на шаге 1. В свойстве TransparencyKey указываем черый цвет (тот цвет, которым закрасили не нужную область изображения).
Шаг 4. Установка FormBorderStyle в None приводит к исчезновению строки заголовка окна с кнопками сворачивания/разворачивания и закрытия окна, поэтому нужно создать эти кнопки вручную. Добавляем из тулбокса (ToolBox) две обычные кнопки для закрытия и сворачивания окна. Одной в свойстве Text указываем «X», а другой «_».

У кнопки «X» в событии OnClick описываем процедуру закрытия окна:
private void button1_Click(object sender, System.EventArgs e)
{
this.Close();
}
А у кнопки с «_» — процедуру сворачивания:
private void button2_Click(object sender, System.EventArgs e)
{
this.WindowState=FormWindowState.Minimized;
}
Шаг 5. Теперь заставим форму перемещаться мышкой. Создаем новую публичную переменную mouse_offset типа Point:
public Point mouse_offset;
Добавляем форме обработчик события MouseDown, и описываем в нем процедуру инициализации переменной mouse_offset:
private void Form1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
mouse_offset = new Point(-e.X, -e.Y);
}
Теперь создаем обработчик события MouseMove нашей формы, в котором и будет производиться определение текущих координат курсора и собственно перемещение формы:
private void Form1_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mouse_offset.X, mouse_offset.Y); // определяем текущие координаты курсора...
Location = mousePos; // ... и перемещаем форму
}
}
Сохраняем приложение и давим F5. Попробуйте перетянуть форму за любой уччасток — она переместится. Кнопка сворачивания свернет форму, а кнопка закрытия — закроет.

Все, конечно, хорошо, но чего-то не хватает...
Добавим плавное появление формы (Fade-In).
За прозрачноссть формы отвечает ее свойство Opacity. Значение 0 — полная прозрачность формы, 1 — полная непрозрачность. Устанавливаем у нашей формы это свойство в 0.
Добавляем на форму таймер (Timer) и включаем его (устанавливаем свойство Enabled в true). Свойство Interval устанавливаем равным 20.
Теперь добавляем обработчик «тиканья» таймера (Tick) со следующим кодом:
this.Opacity += 0.05;
if (this.Opacity >= .95)
{
this.Opacity = 1;
timer1.Enabled = false;
}
Здесь мы в цикле постепенно ослабляем прозрачность формы пока она не станет равной единице, после чего отключаем таймер.
Попробуйте запустить программу, и увидите как форма плавно появляется на экране.
Webmoney Z163628999150, R61715184597
|
25 июня 2009
Не актуально в силу следующей проблемы:
при добавлении других контролов на форму, тех же label-ов или картинок — за них тоже нужно двигать форму.
Ставить каждому новому контролу событие — неверное решение.
Да и работает оно при таком раскладе не верно.
Попробуй к себе текст добавь и потягай
27 июня 2009
Да, есть такое дело, за другие контролы не перетягивается.
В таком случае можно в событии OnLoad формы пройтись по коллекции контролов и добавить новое событие для MouseMove и MouseDown:
Текущие обработчики этих событий это не заменит (будут выполняться оба обработчика).
А проблему с тем, что функция перемещения «работает не верно» можно исправить немного преобразовав функцию-обработчик события onMouseMove:
доработанный пример.
15 Дек 2009
Но плавное появление справедливо олько для Vista или Seven. Или я ощибаюсь?
15 Дек 2009
Ошибаетесь, в xp тоже работает.
16 Дек 2009
У меня при появлении сначала отображается весь рисунок вместе с черным.
15 июня 2010
protected const int WM_NCHITTEST = 0×0084;
protected const int HTCAPTION = 2;
protected override void WndProc (ref Message m)
{
if (m.Msg == WM_NCHITTEST)
{
m.Result = (IntPtr) HTCAPTION;
return;
}
base.WndProc (ref m);
}
Это работает очень даже хорошо. Пример был взят из инета.
Возникает другая проблема: Как теперь свернуть окно по двойному щелчку мыши в произвольном месте формы? Даже если подписаться на событие, оно не будет обрабатываться.