Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
П_З.docx
Скачиваний:
3
Добавлен:
24.08.2019
Размер:
179.91 Кб
Скачать

Рисование прозрачных фигур

Разместите в форме Form1 флажок checkBox1 и положите его свойство Text равным Transparent:, а свойство RightToLeft равным Yes. Измените свойство Text метки label5 Ha Transp.

Определите обработчик события checkedchanged для флажка checkBox1 (листинг 28)

И измените метод DrawFigure (листинг 29).

Листинг 28. Обработчик checkBox1. CheckedChknge

private void checkBoxl_CheckedChanged(object sender, EventArgs e)

{label5.Invalidate();}

Листинг 29. Новый вариант метода DrawFigure ■

private void DrawFigure(Rectangle r, Graphics g)

{switch (figureMode)

case 0:

if (!checkBox1.Checked)

g.FiliRectangie(brush, r); g.DrawRectangle(pen, r); break; case 1:

if (!checkBox1.Checked) g.FillEllipse(brush, r); g.DrawEllipse(pen, r); break;}

При установке флажка Transparent (Прозрачный) во включенное состояние внутренность рисуемых прямоугольников и эллипсов не закрашивается цветом фона. Если установлен прозрачный режим, то сквозь рисунок на метке-образце label5 "просвечивает" ее заголовок Transp.. Следует заметить, что при установке прозрачного режима текущий цвет фона не изменяется; в частности, он по-прежнему используется при очистке изображения (т. е. при ее закрашивании текущим фоновым цветом) с помощью кнопки Clear.

Хотя в GDI+ имеется возможность устанавливать уровень прозрачности цвета мы использовали более простой прием: при установленном режиме прозрачности не вызываются методы FillRectangle и FillEllipse, обеспечивающие заливку указанной фигуры.

Рисование квадратов и окружностей

В класс Form1 добавьте новое поле:

private bool equalSize;

Измените методы PtToRect И pictureBox1_MouseMove (листинг 30).

Листинг 30. Новый вариант методов PtToRect и pictureBox1_MtouseMove

private Rectangle PtToRect(Point pi, Point p2)

{if (equalSize)

{int dx = p2.X - pl.X, dy = p2.Y - pl.Y;

if (Math.Abs (dx) > Math.Abs (dy))

p2.X = pl.X + Math. Sign (dx) * Math.Abs (dy) ; else

p2.Y = pl.Y + Math. Sign (dy) * Math. Abs (dx) /

int х = Math.Min(pi.X, p2.X),

у = Math.Min(pi.Y, p2.Y),

w = Math.Abs(p2.X - pl.X),

h = Math.Abs(p2.Y - pl.Y);

return new Rectangle(x, y, w, h);}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e) {

label1.Text = string.Format("X,Y: {0},{1}", e.X, e.Y); if (startPt == nullPt) return;

if (e.Button == MouseButtons.Left) switch (mode)

{case 0:

Graphics g = Graphics.Fromlmage(pictureBox1.Image);

g.DrawLine(pen, startPt, e.Location);

g.Dispose();

startPt = e.Location; pictureBox1.Invalidate();

break; case 1: case 2:

ReversibleDraw(); movePt = e.Location;

equalSize = Control .ModifierKeys = Keys. Control;

ReversibleDraw(); break;}}

Теперь в режиме Figure можно рисовать фигуры с равными измерениями (квадраты и окружности). Для этого в процессе рисования следует дер­жать нажатой клавишу <Ctrl>. Допускается нажимать и отпускать эту клавишу после начала перемещения мыши; при этом инверсный контур будет автоматически корректироваться, изображая при нажатой клавише <Ctrl> квадратную, а в противном случае — прямоугольную рамку.

Поле equalSize не инициализируется при описании, так как при выполнении конструктора оно, как и все прочие поля, не инициализированные явно, автоматически получит нулевое значение соответствующего типа (т. е. в данном случае значение false).

Фрагмент, добавленный в метод PtToRect (см. листинг 30), пересчитывает одну из координат точки р2 таким образом, чтобы точка р2 оставалась в прежней четверти относительно точки pi, но при этом модули разностей

р2. х - pl.x и р2 . y - pl.Y были равны между собой (в результате точки pi и р2 будут определять вершины квадрата). Изменяется именно точка р2, так как точка pi соответствует начальной точке рисования фигуры и поэтому не может быть изменена.

В данном фрагменте, кроме метода Abs (X) класса Math, находящего модуль числа х, используется метод sign (X), возвращающий 1 при положительном параметре х, -1 при отрицательном и 0 при нулево.

Обратите внимание на то, что поле equalSize переопределяется в обработчике pictureBox1_MouseMove (см. листинг 30) между вызовами метода ReversibleDraw. Это обеспечивает корректное скрытие старого инверсного контура (выполняемое первым вызовом ReversibleDraw) перед рисованием нового.