Расширенная работа с GDI+

Модификация приложения Windows Forms. Подготовка интерфейса и добавление TabControl. Создание и использование вкладок "Просто фон", "Объекты и градиент", " Мой монитор сломался?!", "Векторные часы", "Огонь!!!" и "Дождик" в приложении Windows Forms.

Рубрика Программирование, компьютеры и кибернетика
Вид лабораторная работа
Язык русский
Дата добавления 24.04.2017
Размер файла 2,3 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Лабораторная работа 19: Расширенная работа с GDI+

Содержание

1. Вводная часть

2. Создание приложения Windows Forms

3. Модификация приложения Windows Forms: подготовка интерфейса и добавление TabControl

4. Модификация приложения Windows Forms: вкладка «Просто фон!»

5. Модификация приложения Windows Forms: вкладка «Объекты и градиент»

6. Модификация приложения Windows Forms: вкладка «Мой монитор сломался?!»

7. Модификация приложения Windows Forms: вкладка «Векторные часы»

8. Модификация приложения Windows Forms: вкладка «Огонь!!!»

9. Модификация приложения Windows Forms: вкладка «Дождик»

10. Завершающая часть

11. О приложении к Лабораторной работе № 19

1. Вводная часть

windows forms приложение интерфейс

В этой работе будет рассмотрена расширенная работа с графикой GDI+ в C#. Фактически это «демонстрационная» лабораторная работа, призванная показать богатство возможностей «обычной» системной графики на примере обычного Windows Forms. А этих возможностей на поверку оказывается очень много...

Непосредственно о том, что такое GDI+ уже было рассказано ранее в предыдущей работе практикуму, но повторимся...

Что же такое GDI+? Официальная документация скромно называет её Class-based API, то есть основанным на классах интерфейсе прикладных программ для ОС Windows поколения «не GDI». Так как она встроена в Windows XP и все последующие ОС вплоть до Windows 7, её называют частью этих операционных систем. Часто встречается также определение «библиотека» или «библиотека классов». В действительности, предоставляемый GDI+ набор классов является тонкой оболочкой над множеством обычных функций, реализованных в одной динамической библиотеке GdiPlus.dll.

Итак, GDI+ -- это библиотека, призванная заменить существующий уже больше 11 (или 18, в зависимости от того, как считать) лет интерфейс GDI, являющийся графическим ядром предыдущих версий Windows. Она сочетает в себе (по крайней мере, по замыслу) все достоинства своего предшественника и предоставляет множество новых мощных возможностей. Кроме того, при её проектировании заранее ставилась цель наименее болезненного переноса приложений на 64-битные платформы.

Само слово GDI: Graphics Device Interface, Graphical Device Interface. «Устройство(-а) графического интерфейса» или «интерфейс графического устройства», но проще: «пользовательский интерфейс».

В чём будет заключаться суть нашего приложения? Хм... Во вкладках окна. На каждой вкладке будет демонстрация возможностей по работе с GDI+. Всё просто.

2. Создание приложения Windows Forms

Запускаем Visual Studio 2010, откроется Начальная страница:

Для начала, надо создать проект, для этого выполним последовательно: Файл -> Создать -> Проект… (также можно просто нажать сочетание клавиш Ctrl+Shift+N или пункт «Создать проект…» на Начальной странице):

Рис. 2.1 Создание нового проекта

Выберем слева в пункте Установленные шаблоны язык Visual C#, далее найдём в списке Приложение Windows Forms. Также здесь можно выбрать какой использовать «фреймворк» (набора компонентов для написания программ). В нашем случае выберем.NET Framework 4.

Рис. 2.2 Окно создания нового проекта

В поле Имя вводим LWP19GDIPlus -- это название программы (выбрано по названию лабораторного практикума, номеру и названию работы). В поле Расположение указана конечная директория, где будет находиться весь проект. Выберем расположение удобное для быстрого поиска. В поле Имя решения вводится либо название программы «по умолчанию» из поля Имя автоматически, либо можно ввести своё собственное. Под этим именем будет создана конечная папка проекта (если Имя и Имя решения разные).

Рис. 2.3 Вводим данные нового проекта приложения Windows Forms

После нажатия клавиши ОК. мы увидим сформированный проект и исходный код приложения Windows Forms (не пустого изначально).

Рис. 2.4 Обозреватель решений: состав проекта приложения Windows Forms сформированного средой разработки

Теперь, можно откомпилировать созданную программу, нажав клавишу F5 (Отладка -> Начать отладку или нажав на иконку . Тем самым мы запускаем приложение в режиме отладки (и производим компиляцию debug-версии программы) (Debug выбрано изначально).

Рис. 2.5 Запуск приложения Windows Forms по конфигурации Debug

3. Модификация приложения Windows Forms: подготовка интерфейса и добавление TabControl

Для начала изменим размер нашей единственной формы. Для этого можно потянуть за уголок в нужном направлении на странице визуального представления формы1. Но также размер можно менять на панели свойств этой формы. Для этого нужно поменять значение размера в пикселях (высоту и ширину) в поле Size.

ПРИМЕЧАНИЕ 1: Для перехода на визуальное представление формы, необходимо двойным нажатием в обозревателе решений нажать на значок формы () или выбрать вкладку на панели вкладок с именем <имя формы>.cs [Конструктор].

Задаём следующие параметры формы на панели Свойства:

(Name)

изменим с Form1.cs2 на LWP19Main

^ Поменяем внутреннее имя формы.

Text

изменим с Form1 на Расширенная работа с GDI+ (C#)

^ Поменяем заголовок формы (то, что отображается в шапке приложения слева).

Icon

изменим изображение (иконку) приложения

^ Необходим файл значка *.ico.

Size

изменим со значений 300; 300 на 800; 600

^ Поменяем размер формы.

ПРИМЕЧАНИЕ 2: Для того, чтобы поменять имя файла нашей формы, необходимо выполнить следующее: выделить в обозревателе решений значок формы () и нажать правую кнопку мыши, затем выбрать Переименовать. Ввести необходимое новое имя СОХРАНЯЯ расширение *.cs. После смены имени, автоматически поменяются имена проассоциированных непосредственно с формой файлов:

Разместим на форме единственный элемент: TabControl (), находится в группе Контейнеры панели элементов.

Растянем этот элемент до краёв формы и измени имя элемента:

TabControl

(Name):

TB_Main

Anchor:

Top, Bottom, Left, Right

Изменение последнего свойства потребуется, чтобы весь элемент менял размер при изменении размеров формы.

То, что должно получиться в итоге, показано на рисунке ниже:

Рис. 3.1 Модифицированная форма приложения и расстановка необходимых элементов управления

4. Модификация приложения Windows Forms: вкладка «Просто фон!»

Первая вкладка TabControl будет показана первой при старте приложения. На неё просто необходимо установить что-нибудь простое.

Для начала изменим текст самой вкладки. Выделим элемент управления и перейдём к свойствам (панель Свойства) элемента. Нам нужно свойство TabPages:

Жмём «...» и открываем окно редактирования вкладок:

Рис. 4.1 Редактор коллекции TabPage: меняем Text и Cursor

Для вкладки tabPage1 (имя не будем менять), изменим свойства:

TabPage

Text:

Просто фон!

Cursor:

No

В качестве фона вкладки будет выбрано некое изображение. Пусть это будет изображение с именем Background_Image.jpg (использованное в данной работе изображение можно получить в ZIP-архиве по ссылке в конец этого материала). Для добавления выполним действия: Проект -> Существующий элемент... (Shift+Alt+A), в открывшемся окне находим изображение и жмём Добавить.

Теперь приступаем к коду вкладки. Для начальной вкладки tabPage1 проинициализируем событие Paint (панель свойств, вкладка События):

Код события такой:

private void tabPage1_Paint(object sender, PaintEventArgs e)

{

// При создании вкладки и её прорисовки, вызываем метод DoPaint

// Используем аргумент e для получение параметров рисования (устройста и прямоугольной области)

DoPaint(e.Graphics, e.ClipRectangle);

}

Добавим и сам метод DoPaint в код под событие Paint:

protected void DoPaint(Graphics g, Rectangle clipBox)

{

RectangleF bounds = clipBox;

String welcome = "Расширенная работа с GDI+ (C#):: Вкладка \"Просто фон\"";

Bitmap bg = new Bitmap("/Background_Image.gif"); // Абсолютный путь до изображения

g.DrawImage(bg, bounds); // Рисуем и растягиваем изображение на весь фон вкладки

// Создаём градентную заливку для текста

LinearGradientBrush brush = new LinearGradientBrush(bounds,

Color.FromArgb(130, 255, 0, 0), Color.FromArgb(255, 0, 0, 255),

LinearGradientMode.BackwardDiagonal);

// Создаём форматирование текста и помещаем его в центре вкладки (по вертикали и горизонтали)

StringFormat format = new StringFormat();

format.Alignment = StringAlignment.Center;

format.LineAlignment = StringAlignment.Center;

// Задаём параметры шрифта

Font font = new Font("Verdana", 48, FontStyle.Bold);

g.DrawString(welcome, font, brush, bounds, format);

}

В самом начале файла формы LWP19Main.cs добавим следующую строчку:

using System.Drawing.Drawing2D;

Всё предельно просто. Комментарии расставлены. Собственно этим кодом был реализован простейший пример работы с GDI+.

Откомпилируем и запустим приложение (Debug). Увидим, что текст отрисовывается без сглаживания. Это связано с тем, что в Windows Forms по умолчанию отключается улучшенный режим отрисовки шрифтов. Включить можно, например, так (размещать код перед кодом рисования объекта):

g.SmoothingMode = SmoothingMode.AntiAlias;

В объекте Graphics имеется также соответствующее свойство InterpolationMode. Выигрыш в качестве в данном случае приводит к проигрышу в скорости, поэтому при использовании режима с наивысшим качеством InterpolationModeHighQualityBicubic медленные компьютеры могут выводить изображения больших размеров в течение нескольких секунд (речь идет об экранном выводе, то есть умеренно больших, так как бикубическая интерполяция изображений полиграфического разрешения может длиться минутами и на самых современных компьютерах)! Но только этот метод способен адекватно отображать, например картинку при уменьшении её до 25 процентов (и менее) от оригинала. Этот режим очень поможет различным автоматическим генераторам иконок (thumbnail) изображений в ASP.NET.

На качество (и скорость) вывода растров также влияют некоторые другие установки объектов Graphics. Перечислим их:

Метод

Назначение

SmoothingMode

Как уже говорилось, позволяет указать метод устранения ступенчатости (Anti Aliasing) при выводе примитивов - линий и геометрических фигур.

CompositingMode

Устанавливает или отключает учет прозрачности при наложении растровых изображений.

CompositingQuality

Управляет качеством расчета цветовых компонентов при наложении растров.

PixelOffsetMode

Задает метод учета смещения пикселов при интерполяции. Грубо говоря, определяет, являются ли координаты пикселов (или их центров) целыми числами при расчетах.

RenderingOrigin

Устанавливает позицию начальной точки при псевдосмешении (dithering) цветов в 8- и 16-битных режимах.

5. Модификация приложения Windows Forms: вкладка «Объекты и градиент»

Теперь поработаем с градиентами более с более близкого расстояния. Редактируем вторую вкладку tabPage2 следующим образом:

TabPage

Text:

Объекты и градиент

Cursor:

Hand

Рис. 5.1 Редактор коллекции TabPage: меняем Text и Cursor

На второй вкладке разместим сначала элемент Panel (, группа «Контейнеры» панели элементов), а затем три кнопки. Свойства всего этого дела (имена элементов не трогаем):

Panel

(Name):

panel1

BackColor:

Black

AutoScroll:

True

Button

(Name):

button1

Text:

Прямоугольник

Button

(Name):

Button2

Text:

Треугольник

Button

(Name):

Button3

Text:

Круг

Расстановка элементов выглядит примерно так:

Рис. 5.2 Модифицированная форма приложения и расстановка необходимых элементов управления на второй вкладке

Кнопки находятся внутри элемента Panel (поверх).

Открываем код нашей формы LWP19Main (файл LWP19Main.cs). Ищем:

public LWP19Main()

{

InitializeComponent();

Добавляем после:

DoubleBuffered = true;

Ищем:

public partial class LWP19Main: Form

{

Добавляем после:

// Начало: вкладка "Объекты и градиент"

// Для работы с появлением/скрытием фигур

bool bDrawFigure1 = false;

bool bDrawFigure2 = false;

bool bDrawFigure3 = false;

// Создаём цвета

Color c1 = Color.FromArgb(51, 204, 51);

Color c2 = Color.FromName("Green");

Color c3 = Color.FromArgb(0, 0, 0);

Color c4 = Color.FromArgb(51, 104, 51);

// Конец: вкладка "Объекты и градиент"

Инициализируем событие Paint для элемента Panel второй вкладки:

private void panel1_Paint(object sender, PaintEventArgs e)

{

Graphics g = panel1.CreateGraphics();

// Задаём визуализацию со сглаживанием для объекта Graphics

g.SmoothingMode = SmoothingMode.HighQuality;

// Массив точек треугольника

Point[] triangle = { new Point(80, 150), new Point(200, 50), new Point(320, 150) };

// Задаём перья с цветами c1 и c2 и толщиной в 1 пиксель

Pen pen1 = new Pen(c1, 1);

Pen pen2 = new Pen(c2, 1);

// Заливка и цвета градиента

Brush brush1 = new LinearGradientBrush(triangle[0], triangle[2], c1, c4);

Brush brush2 = new LinearGradientBrush(triangle[0], triangle[2], c3, c2);

if (bDrawFigure1)

{

// Заливаем цветом прямоугольник

g.FillRectangle(brush2, new Rectangle(100, 150, 200, 100));

}

if (bDrawFigure2)

{

// Заливаем цветом треугольник

g.FillPolygon(brush2, triangle);

}

if (bDrawFigure3)

{

// Заливаем цветом эллипс

g.FillEllipse(brush1, new Rectangle(175, 175, 50, 50));

}

}

И последовательно инициализируем двойным нажатием события каждой кнопки. Событие Click для каждой из кнопок будет таким:

private void button1_Click(object sender, EventArgs e)

{

if (bDrawFigure1 == true) { bDrawFigure1 = false; }

else bDrawFigure1 = true;

panel1.Invalidate();

}

private void button2_Click(object sender, EventArgs e)

{

if (bDrawFigure2 == true) { bDrawFigure2 = false; }

else bDrawFigure2 = true;

panel1.Invalidate();

}

private void button3_Click(object sender, EventArgs e)

{

if (bDrawFigure3 == true) { bDrawFigure3 = false; }

else bDrawFigure3 = true;

panel1.Invalidate();

}

Компилируем (Debug) и запускаем. Переходим на закладку «Объекты и градиент» и нажимаем на кнопочки... Любуемся, как появляется «домик» с круглым окном...

6. Модификация приложения Windows Forms: вкладка «Мой монитор сломался!»

Следующая вкладка будет реализовывать вот что: откроем её, нажмём где-нибудь на свободном участке вкладки левую кнопку мыши и потащить курсор. Выделенный участок инвертируется (инвертируются его цветовая палитра) даже за пределами формы -- это такое взаимодействие высокоуровневой GDI+ и низкоуровневой GDI...

Создаём новую вкладку tabPage3. Для создания вкладки выделяем мышкой TabControl и на панели свойств в области команд жмём «Добавить вкладку». Свойства новой вкладки:

TabPage

Text:

Объекты и градиент

Cursor:

Cross

Накидаем на вкладку различных элементов, каких не важно. В нашем случае на вкладку было помещено две кнопки, два TextBox и один Label. Изменим свойства элементов управления как угодно? Изменим цвет фона элемента, параметры шрифты и прочее.

Рис. 6.1 Модифицированная форма приложения и расстановка необходимых элементов управления на третьей вкладке

Теперь, последовательно, для вкладки tabPage3 (нужно переключиться на неё в конструкторе и выделить область самой вкладки) инициализируем три события: MouseDown, MouseMove и MouseUp:

Код дополнительной переменной, всех событий и двух дополнительных методов будет таким:

Rectangle frameRect; // Вкладка "Мой монитор сломался?!"

private void tabPage3_MouseDown(object sender, MouseEventArgs e)

{

if (e.Button == MouseButtons.Left)

{

// Фиксируем стартовую точку

frameRect.Location = new Point(e.X, e.Y);

frameRect.Size = new Size(0, 0);

}

base.OnMouseDown(e); // Вызываем базовый метод

}

private void tabPage3_MouseMove(object sender, MouseEventArgs e)

{

if (e.Button == MouseButtons.Left)

{

DrawFrame(); // Стираем старый прямоугольник

frameRect.Width = e.X - frameRect.Left;

frameRect.Height = e.Y - frameRect.Top;

DrawFrame(); // Рисуем новый прямоугольник

}

base.OnMouseMove(e); // Вызываем базовый метод

}

private void tabPage3_MouseUp(object sender, MouseEventArgs e)

{

if (e.Button == MouseButtons.Left)

{

DrawFrame(); // Стираем старый прямоугольник

frameRect.Size = new Size(0, 0);

}

base.OnMouseUp(e); // Вызываем базовый метод

}

protected void DrawFrame()

{

if (!frameRect.Size.IsEmpty)

{

Rectangle r = RectangleToScreen(frameRect);

// Собственно, инвертируем цвета

ControlPaint.FillReversibleRectangle(r, Color.FromArgb(40, 0, 0, 160));

}

}

protected override void OnLoad(EventArgs e)

{

SetStyle(ControlStyles.UserPaint, true);

SetStyle(ControlStyles.AllPaintingInWmPaint, true);

SetStyle(ControlStyles.DoubleBuffer, true);

base.OnLoad(e);

}

Обратим внимание на метод OnLoad: здесь идёт включение режима двойной буферизации. Для его включения необходимо в окне, в которое производится отрисовка (например, элементе управления или форме) установить флаги UserPaint, AllPaintingInWmPaint и DoubleBuffer перечисления System.Windows.Forms.ControlStyles.

Вывод графики довольно заметно ускоряется (несмотря на необходимость дополнительного переноса на экран).

Компилируем (Debug) и запускаем. Переходим на третью вкладку и инвертируем цвета у всего, до чего дотягивается мышка...

7. Модификация приложения Windows Forms: вкладка «Векторные часы»

Данная вкладка отображает текущее время на стилизованном «аналоговом» циферблате (без использования изображений и сторонних ресурсов). В ней использован большой набор примитивов: прямоугольники, эллипсы и отрезки прямых. Для расчёта их координат используются не геометрические преобразования GDI+, а простые вычисления. Что действительно заслуживает внимания, так это отображение стрелок часов. Каждая стрелка рисуется всего одним вызовом метода DrawLine!

Для часиков создаём четвёртую вкладку tabPage4 со свойствами:

TabPage

Text:

Векторные часы

Cursor:

AppStarting

Добавляем на форму таймер (Timer) со свойствами:

Timer

(Name):

timer1

Interval:

1000

Инициализируем событие первого таймера Tick:

private void timer1_Tick(object sender, EventArgs e)

{

tabPage4.Text = "Векторные часы: " + DateTime.Now.ToLongTimeString();

Invalidate();

}

Инициализируем событие Selected для главного элемента TabControl со следующим кодом:

private void TB_Main_Selected(object sender, TabControlEventArgs e)

{

if (e.TabPage.Name == tabPage4.Name) timer1.Enabled = true;

else timer1.Enabled = false;

}

Этот код нужен вот для чего: если выбираем активной вкладкой, вкладку номер четыре, то запускаем таймер.

Инициализируем событие загрузки формы Load:

private void LWP19Main_Load(object sender, EventArgs e)

{

SetStyle(ControlStyles.AllPaintingInWmPaint, true);

SetStyle(ControlStyles.DoubleBuffer, true);

SetStyle(ControlStyles.UserPaint, true);

}

И, наконец, инициализируем событие Paint вкладки tabPage4, а также дополнительный метод:

private Point RadialPoint(int radius, int seconds)

{

Point ptCenter = new Point(tabPage4.ClientRectangle.Width / 2, tabPage4.ClientRectangle.Height / 2);

double angle = -((seconds - 15) % 60) * Math.PI / 30; // Вычисляем угол на "окружности" (шаг)

Point ret = new Point(

ptCenter.X + (int)(radius * Math.Cos(angle)),

ptCenter.Y - (int)(radius * Math.Sin(angle)));

return ret;

}

private void tabPage4_Paint(object sender, PaintEventArgs e)

{

// Создаём объект часов

DateTime dt = DateTime.Now;

Graphics g = e.Graphics;

g.SmoothingMode = SmoothingMode.HighQuality;

// Вычисляем центральную точку для циферблата

Point ptCenter = new Point(tabPage4.ClientRectangle.Width / 2, tabPage4.ClientRectangle.Height / 2);

// Вычисляем радиус циферблата на основе размеров вкладки

int radius = Math.Min(tabPage4.ClientRectangle.Width, tabPage4.ClientRectangle.Height) / 2;

using (LinearGradientBrush br = new LinearGradientBrush(tabPage4.ClientRectangle, Color.White, Color.Azure, LinearGradientMode.BackwardDiagonal))

{

//br.SetSigmaBellShape(.5f, 1.0f);

// Заполняем циферблат градиентом

g.FillEllipse(br, ptCenter.X - radius, ptCenter.Y - radius, radius * 2, radius * 2);

}

// Рисуем эллипс цифербалата

using (Pen pen = new Pen(Color.Black))

g.DrawEllipse(pen, ptCenter.X - radius, ptCenter.Y - radius, radius * 2, radius * 2);

// Цикл минуты

for (int minute = 0; minute < 60; minute++)

{

Point pt = RadialPoint(radius - 10, minute);

using (SolidBrush br = new SolidBrush(Color.Black))

{

if ((minute % 5) == 0)

g.FillRectangle(br, pt.X - 3, pt.Y - 3, 6, 6);

else

g.FillRectangle(br, pt.X - 1, pt.Y - 1, 2, 2);

}

}

// Рисуем стрелку часов (от центра до позиции на циферблате)

using (Pen pen = new Pen(Color.Black, 8))

{

pen.StartCap = LineCap.Flat;

pen.EndCap = LineCap.DiamondAnchor;

float[] compVals = new float[] { 0.0f, 0.2f, 0.5f, 0.7f, 0.9f, 1.0f };

pen.CompoundArray = compVals;

g.DrawLine(pen, RadialPoint(15, 30 + dt.Hour * 5 + dt.Minute / 12), RadialPoint((int)(radius * 0.75), dt.Hour * 5 + dt.Minute / 12));

}

// Рисуем минутную стрелку

using (Pen pen = new Pen(Color.FromArgb(100, 0, 0, 0), 6))

{

pen.StartCap = LineCap.RoundAnchor;

pen.EndCap = LineCap.Round;

g.DrawLine(pen, RadialPoint(15, 30 + dt.Minute), RadialPoint((int)(radius * 0.8), dt.Minute));

}

// Русуем секундную стрелку

using (Pen pen = new Pen(Color.FromArgb(50, 150, 50, 25), 4))

{

pen.CustomEndCap = new AdjustableArrowCap(4, 6, true);

g.DrawLine(pen, RadialPoint(20, dt.Second + 30), RadialPoint(radius - 2, dt.Second));

}

using (SolidBrush br = new SolidBrush(Color.FromArgb(100, Color.Wheat)))

g.FillEllipse(br, ptCenter.X - 5, ptCenter.Y - 5, 10, 10);

}

Компилируем (Debug) и запускаем. Переходим на закладку «Векторные часы», чем запускаем таймер, заголовок вкладки будет отображать текущее время, а на самой вкладке видим круглые стрелочные часы собранные из примитивов. Мило!

8. Модификация приложения Windows Forms: вкладка «Огонь!!!»

На этот раз будем имитировать горение огня (стена огня). Для создания эффекта огня будем использовать генерацию случайных чисел каждую миллисекунду. Однако, отображать сам огонь будем не на вкладке TabControl, а в новой форме. Это связано с «некрасивым» обновлением вкладки при рисовании огня (возникает заметное мерцание).

Создаём новую вкладку со свойствами:

TabPage

Text:

Огонь!!!

Cursor:

No

Добавляем новую форму с именем LWP19Fire и не меняем какие-либо свойства формы (ну, разве что значок). Добавить форму можно так: Проект -> Добавить форму Windows... (а затем переименовать класс формы); либо использовать стандартное добавление: Проект -> Добавить новый элемент... (Ctrl+Shift+A) и далее указать Имя: LWP19Fire).

Редактируем код события Selected для TabControl. Добавляем туда строчки:

if (e.TabPage.Name == tabPage5.Name)

{

tabPage5.BackColor = Color.Black;

LWP19Fire Fire = new LWP19Fire();

Fire.ShowDialog();

}

Выбор данной вкладки («Огонь!!!») вызовет экземпляр модальной формы LWP19Fire.

Теперь редактируем код новой формы. Вначале добавим следующий код (в директивы using):

using System.Drawing.Imaging;

Теперь, найдём в коде формы строчки:

public partial class LWP19Fire: Form

{

Добавим после:

// Начало: вкладка "Огонь!!!"

private Bitmap buf; // Буфер для графики

private Random random = new Random(DateTime.Now.Millisecond); // Истоник данных (Random)

private const int width = 640;

private const int height = 320;

// Конец: вкладка "Огонь!!!"

Метод LWP19Fire() редактируем так:

public LWP19Fire()

{

InitializeComponent();

// Инициализируем источник для последующего использования

random = new Random();

// Устанавливаем начальные параметры вкладки

this.Text = "Расширенная работа с GDI+ (C#):: форма для вкладки \"Огонь!!!\"";

this.ClientSize = new Size(width, height);

this.MaximizeBox = false;

this.FormBorderStyle = FormBorderStyle.FixedDialog;

this.BackColor = Color.Black;

SetStyle(ControlStyles.Opaque, true);

// Вызываем событие рисования (для метода DoFire)

this.Paint += new PaintEventHandler(this.DoFire);

// Генерируем палитру 640x480 (на основе Bimtap с 256 цветами на пиксель)

buf = new Bitmap(width, height, PixelFormat.Format8bppIndexed);

ColorPalette pal = buf.Palette;

// Заполняем палитру, используя 64-цветные блоки:

// чёрный с красным, красный с желтым, желтый с белым, белый.

// Так как каждый диапазон составляет 64 цветов и RGB охватывает 256 значений,

// использовуем левый сдвиг (<<) по массиву

for (int i = 0; i < 64; i++)

{

pal.Entries[i] = Color.FromArgb(i << 2, 0, 0);

pal.Entries[i + 64] = Color.FromArgb(255, i << 2, 0);

pal.Entries[i + 128] = Color.FromArgb(255, 255, i << 2);

pal.Entries[i + 192] = Color.FromArgb(255, 255, 255);

}

buf.Palette = pal;

}

И добавим метод для переопределённого события Paint формы:

// Метод рисования "огня"

private void DoFire(object src, PaintEventArgs e)

{

// Блокируем растр, чтобы мы смогли записывать в него напрямую

BitmapData buflock = buf.LockBits(

new Rectangle(Point.Empty, buf.Size),

ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

// Записываем "огонь"

// Используем указатели, потому блок "unsafe"

unsafe

{

// Извлекает указатель на верхнюю строку развёртки изображения

Byte* bufdata = (Byte*)buflock.Scan0;

Byte* bufbottom = bufdata + ((height - 1) * width);

Byte* i; int v;

// Используем случайную нижней линию в качестве источника "огня"

for (int x = 0; x < width; x++)

{

*(bufbottom + x) = (Byte)random.Next(100, 255);

}

// Для каждого пикселя в изображении,

// среднее значение пикселей, один справа, один снизу

// и один в левом нижнем углу. Достигаем порог 0,

// и пишем на текущей позиции

for (i = bufdata; i < bufbottom; i++)

{

v = *i + *(i + 1) + *(i + height) + *(i + height - 1);

v /= 4;

if (v < 0) v = 0;

*i = (Byte)v;

}

}

// Разблокируем изображение и рисуем на его на форме

buf.UnlockBits(buflock);

e.Graphics.DrawImageUnscaled(buf, 0, 0);

this.Invalidate();

}

Компилируем (Debug) и запускаем. Переходим на закладку «Огонь!!!», любуемся на огонь (можно любоваться вечно, не правда ли?).

9. Модификация приложения Windows Forms: вкладка «Дождик»

Последняя вкладка будет вызывать дождь. Внутри вкладки. Опять же, как и в случае с часами и огнём, не будем использовать сторонних ресурсов. Разве что можно добавить звуки дождя.

Для этого нам понадобиться новая вкладка со свойствами:

TabPage

Text:

Дождик

Cursor:

PanSouth

Один новый таймер со свойствами:

TabPage

(Name):

timer2

Interval:

60

Один PictureBox, растянутый на всю новую вкладку со свойствами:

PictureBox

(Name):

pictureBox1

Anchor:

Top, Bottom, Left, Right

Код для события Selected элемента TabControl:

if (e.TabPage.Name == tabPage6.Name) timer2.Enabled = true;

else timer2.Enabled = false;

После закрывающей скобки предыдущего события в файле LWP19Main.cs добавим:

// Начало: вкладка "Дождик"

private static Image _raindropImage;

private readonly List<Raindrop> _raindrops;

// Конец: вкладка "Дождик"

#region Класс Raindrop

private class Raindrop

{

private static readonly Random random = new Random(DateTime.Now.Millisecond);

// Удаление от экрана

private float _depth;

// Положение

private PointF _location;

// Прямоугольник для отрисовки

private Rectangle _rectangleToDraw;

// Скорость

private PointF _speed;

public Raindrop(Rectangle rectangleToDraw)

{

_rectangleToDraw = rectangleToDraw;

SetRandomLoc();

}

public void UpdatePosition()

{

// Вертикальная скрость

_location.Y += _speed.Y;

// Горизонтальная скорость

_location.X += _speed.X;

if (_location.Y > _rectangleToDraw.Height)

SetRandomLoc();

}

private void SetRandomLoc()

{

// Максимально удаление

const int MAX_DEPTH = 10;

_depth = random.Next(MAX_DEPTH) + 1;

const int MIN_SPEED = 100;

const int SPEED_DISPERSION = 20;

_speed.X = 5;

// Чем дальше капля от экрана, тем она медленнее падает

_speed.Y = (MIN_SPEED + random.Next(SPEED_DISPERSION)) / _depth;

// Необходимо расширить область, в которой появляются капли

const int DY = 200;

int locX = random.Next(_rectangleToDraw.Width + DY) - DY;

int locY = -random.Next(_rectangleToDraw.Height) - _raindropImage.Height;

// Точка возникновения капли

_location = new PointF(locX, locY);

}

public void Draw(Graphics g)

{

// Масштаб текстуры

float scale = 2 / _depth;

g.DrawImage(_raindropImage, _location.X, _location.Y, _raindropImage.Width * scale,

_raindropImage.Height * scale);

}

}

#endregion

Инициализируем событие второго таймера Tick:

private void timer2_Tick(object sender, EventArgs e)

{

// Обновляем положение капель

foreach (Raindrop raindrop in _raindrops)

raindrop.UpdatePosition();

// Перерисовываем картинку

pictureBox1.Refresh();

}

И событие Paint для PictureBox:

private void pictureBox1_Paint(object sender, PaintEventArgs e)

{

// Отрисовываем капли

foreach (Raindrop raindrop in _raindrops)

raindrop.Draw(e.Graphics);

}

Готово. Можно компилировать и проверять работоспособность.

10. Завершающая часть

Компилируем приложение (Release) и запускаем. После запуска на первой вкладке видим (можно менять размер формы и наблюдать за изменениями при рисовании):

Рис. 10.1 Модифицированное приложение Windows Forms: вкладка «Просто фон!»

Переходим на следующую вкладку и нажимаем на кнопки:

Рис. 10.2 Модифицированное приложение Windows Forms: вкладка «Объекты и градиент»

Переходим на следующую вкладку и жмём левую кнопку мыши на пусто месте. Ведем курсор в любой угол экрана:

Рис. 10.3 Модифицированное приложение Windows Forms: вкладка «Мой монитор сломался?!»

На следующей вкладке запускаются часы:

Рис. 10.4 Модифицированное приложение Windows Forms: вкладка «Векторные часы»

А на следующий горит огонь:

Рис. 10.5 Модифицированное приложение Windows Forms: вкладка «Огонь!!!»

Завершаем всю дождём:

Рис. 10.6 Модифицированное приложение Windows Forms: вкладка «Дождик»

Если требуется добавить звуки дождя (есть на чём услышать):

Отредактируем код события Selected для последней вкладки:

if (e.TabPage.Name == tabPage6.Name)

{

timer2.Enabled = true;

player.SoundLocation = "/Raindrop.wav";

player.Play();

}

else

{

timer2.Enabled = false;

player.Stop();

}

И добавим директиву using в начало файла с кодом:

using System.Media;

И добавим до метода Selected строчку с кодом:

SoundPlayer player = new SoundPlayer();

11. О приложении к Лабораторной работе № 19

Получившуюся программу (LWP19GDIPlus.exe), собранную из кусков кода приведённых в данной лабораторной работе, а также архив с фоновым изображением для первой вкладки (Background_Image.zip), использованный в данной работе, можно загрузить по ссылке в конце этого материала.

Размещено на Allbest.ru

...

Подобные документы

  • Общие положения по программированию в интерфейсе Windows Forms. Среда разработки MicrosoftVisualStudio, ее главные особенности и характеристика. Создание эмулятора пункта меню Microsoft Office Word "Формат-Шрифт" с использованием интерфейса Windows Forms.

    курсовая работа [3,4 M], добавлен 26.01.2013

  • Описание платформы NET Framework. База данных Microsoft Access. Разработка Windows приложения. Модель программирования Windows Forms. Функциональное назначение программы. Входные и выходные данные. Требования к техническому и программному обеспечению.

    курсовая работа [2,2 M], добавлен 15.03.2015

  • Сведения об окружности, ее радиус и площадь. Разработка программы для вычисления площади круга и длины окружности по заданному радиусу с использованием Windows.Forms-приложений. Пошаговая инструкция; описание главного окна, код, примеры работы программы.

    курсовая работа [818,6 K], добавлен 14.09.2014

  • Разработка программного приложения Windows Forms для работы с базой данных на языке высокого уровня в автономном режиме с использованием ADO.NET. Создание консольных приложений (варианты метода Main), выполнение запросов к SQL серверу и листинг программ.

    курсовая работа [2,4 M], добавлен 16.06.2014

  • Разработка проекта с помощью встроенных средств языка C#, на базе сетевого стека и сетевых функций Windows. Специфика создания удобного интерфейса программы с использованием Windows Forms, которая способна пересылать данные на удалённый компьютер.

    курсовая работа [162,6 K], добавлен 16.06.2013

  • Ядро Windows 98. Роль 16-разрядных модулей ядра. Проблемы быстродействия. Кооперативная и вытесняющая многозадачность. Улучшенное использование ресурсов в Windows 98. Использование WordArt. Программа MS Outlook Express: создание и отправка сообщений.

    контрольная работа [120,4 K], добавлен 14.04.2005

  • Изучение пользовательского интерфейса Windows XP, рабочий стол, учетные записи пользователей и их удаление, главное меню, панели инструментов. Папки и файлы, их создание, перемещение и копирование, удаление и восстановление, атрибуты файловых объектов.

    лабораторная работа [251,6 K], добавлен 07.10.2009

  • Характеристика операционной системы. История развития Windows. Сравнительная характеристика версий Windows. Элементы и инструменты Windows XP. Прикладные программы в Windows XP. Работа настольных и портативных компьютеров под управлением Windows.

    доклад [19,1 K], добавлен 16.10.2011

  • Обзор технологии COM (Component Object Technology). Особенности графического интерфейса пользователя и методы его реализации. Интерфейс операционных систем Microsoft Windows: работа с папками, файлами и окнами, использование буфера обмена, проводник.

    контрольная работа [6,4 M], добавлен 16.04.2011

  • Универсальная многоцелевая сетевая операционная система Windows NT Server. Использование Windows NT Workstation как невыделенного сервера в одноранговых сетях и в качестве клиента сетей. Операционные системы Windows 2003, Windows Vista и Windows 7.

    презентация [6,2 K], добавлен 23.10.2013

  • Техника создания графики при помощи API функций, экспортируемых библиотекой GDI32.DLL. Разработка на языке программирования С++ в среде программирования Microsoft Visual C++ программы для отображения часов реального времени в цифровом и аналоговом виде.

    курсовая работа [2,8 M], добавлен 27.01.2010

  • Реализация информационно-справочной системы "Отдел кадров" на языке программирования, с использованием технологии сериализации объектов. Средства конструктора баз данных Windows Forms. Обработка информации и соответствующие организационные ресурсы.

    отчет по практике [95,7 K], добавлен 09.08.2015

  • Создание приложения Windows Forms в среде Microsoft Visual Studio 2008. Разработка программы "Курсовой" для организации работы по учёту курсовых работ в учебных заведениях с возможностью добавления, удаления, редактирования и поиска информации.

    курсовая работа [2,2 M], добавлен 28.06.2011

  • История создания. Windows 9x/NT. Операционная система Microsoft Windows. Преимущества и недостатки Windows. Некоторые клавиатурные комбинации Windows 9x и NT. Windows XP Professional. Наиболее совершенная защита.

    реферат [19,3 K], добавлен 18.07.2004

  • Память ПК. Назначение и виды памяти. Windows. Объекты пользовательского интерфейса и его настройка. Назначение и характеристки Windows. Многозадачность и архитектура Windows. Графический интерфейс Windows - его настройка, рабочие характеристики.

    контрольная работа [27,3 K], добавлен 06.06.2008

  • История ОС семейства Windows. Основные принципы администрирования ОС. Создание домашней группы. Присоединение к домашней группе или ее создание. Особенности ОС Windows 7. Анализ уязвимостей Microsoft Windows 7. Особенности версий ОС Windows 7.

    курсовая работа [2,2 M], добавлен 13.12.2010

  • Создание папки на рабочем столе. Отличия значков ярлыка и файла. Функции монитора, отображение информации о приложениях Windows на рабочем столе. Элементная база ЭВМ третьего поколения. Характеристика операционной системы Windows, свойства информации.

    тест [73,5 K], добавлен 26.12.2011

  • Краткое описание версий Windows XP: Professional Edition, Home Edition, Tablet PC Edition, Media Center Edition, Embedded, XP 64-bit Edition, XP Edition N, XP Starter Edition. Установка Windows XP. Характеристика интерфейса и нововведений Windows 7.

    контрольная работа [1,8 M], добавлен 14.03.2011

  • Архитектурная организация ЭВМ основных классов и типов. Классификация компьютеров по поколениям. Операционные системы: Windows 95, Windows XP и Windows Vista. Защита от компьютерных вирусов: сканирование, эвристический анализ, антивирусные мониторы.

    контрольная работа [122,9 K], добавлен 08.04.2009

  • Головні параметри і характеристики технології Wi-Fi. Огляд її стандартів та частотних каналів. Робота з компонентами Windows Forms. Техніко-економічне обґрунтування програми. Охорона праці та забезпечення безпечних, нешкідливих і сприятливих умов праці.

    дипломная работа [1,4 M], добавлен 24.07.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.