Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Part6(9-прилож)+++а.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.82 Mб
Скачать

9.7. Событие Paint и его обработчик

Если прикладное окно программы примера 9.6.1 свернуть, а потом развернуть или же изменить его размер, то представленная в нём информация исчезнет. Дело в том, что операционная система Windows не заботится о восстановлении содержимого окна при его разрушении и возлагает его восстановление на само Windows-приложение, то есть на программиста.

При всяком разрушении окна операционная системаWindows посылает приложению событие Paint, и приложение реагирует на него предопределённой функцией-обработчиком OnPaint() в языках C# и C++/CLI или функцией-обработчиком paint() в языке Java(J#), пустых по умолчанию, то есть ничего не отображающих в окне. Переопределив функцию OnPaint() или paint(), приложение будет рисовать в области клиента окна что-то в соответствии с её реализацией. В описание переопределённой функции на языке C# и C++/CLI надлежит поместить ключевое слово override. Функции Paint() и paint() относятся к виртуальным функциям, о которых подробно рассказано в разделе 13.1.

Перерисовку окна может осуществить и программист, вызвав специальную функцию Invalidate() в языках C# и C++/CLI или функцию repaint() в языке Java(J#). Вызов этих функций генерирует событие Paint.

Итак, чтобы заставить перерисовываться область клиента окна, необходимо только переопределить функцию перерисовки, имеющую формат:

C++/CLI.

protected: virtual void OnPaint (PaintEventArgs ^e) override;

C#.

protected override void OnPaint (PaintEventArgs e);

Функция реагирует на событие, определённое как

C++/CLI.

public: event PaintEventHandler ^Paint;

C#.

public event PaintEventHandler Paint;

Событие Paint использует делегат:

C++/CLI.

public: delegate void PaintEventHandler (Object ^sender, PaintEventArgs ^e);

C#.

public delegate void PaintEventHandler (object sender, PaintEventArgs e);

Для языка Java(J#) функция перерисовки имеет формат:

Java(J#).

public void paint (Graphics g);

[C++]

Пример 9.7.1 иллюстрирует использование событий, возникающих при нажатии на клавишу мыши и при перерисовке области клиента прикладного окна.

Пример 9.7.1. Программа рисования ломаной линии.

Приложение создаёт главное окно и ожидает нажатия левой клавиши мыши. При нажатии на клавишу рисуется линия из текущей точки в точку носика указателя мыши. После этого текущая точка переносится в точку носика указателя мыши, и приложение снова ждёт нажатия левой клавиши мыши. Прикладное окно с нарисованной ломаной линией изображено на рис. 10.7.1.

Рис.9.7.1. Прикладное окно программы рисования ломаной линии

Ниже приводится программа:

///////////////

// C#

using System;

using System.Drawing;

using System.Windows.Forms;

class CLine : Form // Класс прикладного окна

{

Point [ ] points; // Массив точек носика курсора мыши

int len; // Текущая длина массива points

public CLine( ) // Конструктор

{

// Привязать к событию MouseDown функцию OurMouseDown

MouseDown += new MouseEventHandler (OurMouseDown);

Text= "Line"; // Заголовок прикладного окна

points= new Point [20]; // Создать массив points в куче

len= 0; // Инициализировать len

}

// Перерисовать область клиента окна

protected override void OnPaint (PaintEventArgs arg)

{

base.OnPaint (arg);

for (int i=0; i < len-1; i++) // Перебрать массив точек

arg.Graphics.DrawLine // Нарисовать отрезок линии

(new Pen (Color.Blue), points[i], points[i+1]);

}

// Обработать событие MouseDown мыши

void OurMouseDown (object sender, MouseEventArgs arg)

{

// Реагировать только на левую клавишу мыши

if (arg.Button == MouseButtons.Right) return;

if (len < 20) // Если есть место в массиве points, то

{ // поместить в массив точку

points[len].X= arg.X; // Координата X носика курсора мыши

points[len].Y= arg.Y; // Координата Y носика курсора мыши

len++;

}

Invalidate ( ); // Перерисовать

}

static void Main ( ) // Главная функция

{

Application.Run (new CLine ( )); // Выполнить приложение

}

}

///////////////

// C++/CLI

#include "stdafx.h"

#using <System.Drawing.dll>

#using <System.Windows.Forms.dll>

using namespace System;

using namespace System::Drawing;

using namespace System::Windows::Forms;

ref class CLine : Form // Класс прикладного окна

{

array<Point^> ^points; // Массив точек носика курсора мыши

int len; // Текущая длина массива points

public:

CLine( ) // Конструктор

{

// Привязать к событию MouseDown функцию OurMouseDown

MouseDown += gcnew MouseEventHandler (this,

&CLine::OurMouseDown);

Text= "Line"; // Заголовок прикладного окна

points= gcnew array<Point^> (20); // Создать массив points в куче

len= 0; // Инициализировать len

}

protected:

// Перерисовать область клиента окна

virtual void OnPaint (PaintEventArgs ^arg) override

{

Form::OnPaint (arg);

for (int i=0; i < len-1; i++) // Перебрать массив точек

arg->Graphics->DrawLine // Нарисовать отрезок линии

(gcnew Pen (Color::Blue), *points[i], *points[i+1]);

}

// Обработать событие MouseDown мыши

void OurMouseDown (Object ^sender, MouseEventArgs ^arg)

{

if (len < 20) // Если есть место в массиве points, то

{

points[len]=gcnew Point (arg->X, arg->Y); // поместить в массив

len++;

}

Invalidate ( ); // Перерисовать

}

};

void main ( )

{

Application::Run (gcnew CLine ( ));

}

///////////////

// Java и J#

import java.awt.*;

import java.awt.event.*;

class CLine extends Frame // Класс прикладного окна

{

Point [ ] points; // Массив точек носика курсора мыши

int len; // Текущая длина массива points

public CLine( ) // Конструктор

{

setTitle ("Line"); // Установить заголовок прикладного окна

setSize (400, 200); // Установить размер окна

//this.setBackground (Color.lightGray);

points= new Point [20]; // Создать массив points точек в куче

len= 0; // Инициализировать len

// Реализовать обработчик события мыши, применив

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

this.addMouseListener (new MouseAdapter ( )

{

public void mousePressed (MouseEvent mE)

{

// Реагировать только на левую клавишу мыши

if((mE.getModifiers()&Event.META_MASK)>0) return;

if (len < 20) // Если есть место в массиве points

{

points[len]= mE.getPoint (); // Координаты

// носика курсора мыши len++;

}

repaint ( );

}

});

this.addWindowListener (new OurWindowAdapter());

}

// Перерисовать область клиента окна

public void paint (Graphics g)

{

g.setColor (Color.blue);

for (int i=0; i < points.length-1; i++) // Перебрать массив точек

{

g.drawLine( // Нарисовать отрезок линии

points[i].x, points[i].y ,points[i+1].x, points[i+1].y);

}

}

public static void main ( ) // Главная функция

{

CLine line= new CLine ( );

line.show ( );

}

}

// Класс адаптера окна

class OurWindowAdapter extends WindowAdapter

{

public void windowClosing (WindowEvent wE)

{

System.exit (0);

}

}

C#. Класс CLine прикладного окна, порождённый из базового класса Form, содержит закрытый массив точек points, соответствующих координатам носика мыши нажатых клавиш, и текущую длину len этого массива.

При создании объекта-окна конструктор инициализирует данные класса CLine, создав массив points из 20 точек в куче и присвоив его текущей длине len значение 0. Кроме этого конструктор подписывает обработчик OurMouseDown() на событие MouseDown клавиши мыши и посредством свойства Text формы определяет заголовок “Line” прикладного окна.

Рассмотрим работу приложения. После запуска приложения появилось прикладное окно. При создании окна конструктор класса Cline, создав массив из 20 точек, присвоит длине массива len начальное значение и подпишет обработчик OurMouseDown() на событие MouseDown. При появлении окна сгенерируется событие Paint и, как следствие, выполнится наш переопределённый обработчик OnPaint(), который в виду нулевого значения переменной len не рисует ломаную линию в области клиента. Таким образом, при появлении прикладного окна его область клиента пуста. Приложение ждёт события MouseDown от нажатия левой клавиши мыши и события от закрытия прикладного окна. При нажатии левой клавиши мыши выполнится обработчик OurMouseDown(). Обработчик OurMouseDown(), воспользовавшись параметром arg типа MouseEventArgs, извлекает значения координат носика курсора нажатой клавиши мыши и присваивает их текущему элементу массива points точек. Затем продвигается индекс len массива. Если индекс len выходит за границы массива, то пополнения массива новыми точками не будет. Перед завершением обработчик OurMouseDown() вызывает функцию Invalidate(), которая генерирует событие Paint, обеспечивая тем самым выполнение функции OnPaint(). Ломаная линия перерисовывается в окне.

Функция OnPaint() использует графический объект класса Graphics, извлекая его из структуры PaintEventArgs с помощью свойства Graphics и обратившись к функции DrawLine() рисования линии. В качестве аргумента функция DrawLine() использует объект-перо синего цвета.

Ломаная линия рисуется циклически, при этом в каждом цикле рисуется только один отрезок линии синего цвета.

C++/CLI. Программа на языке C++/CLI схожа с программой на языке C#, поскольку применяются те же классы библиотеки .NET Framework. Обращает на себя внимание иное описание и использование массива точек. В управляемом классе CLine применён управляемый массив points, который описан с применением слова array и является массивом дескрипторов на объекты точек, размещенных в управляемой куче. При нажатии на клавишу мыши обработчик присваивает очередному дескриптору массива ссылку на созданный в куче объект точки, содержащей координаты носика мыши. А функция paint() перерисовки использует через дескриптор эти объекты при рисовании ломаной линии.

Обратите внимание, что заголовок функции OnPaint() языка C++/CLI отличается от заголовка функции OnPaint() языка C#: используется ключевые слово virtual, а слово override стоит в конце заголовка.

Java. Так же, как и в программе на C#, программа на языке Java использует графический класс Graphics в предопределённой функции перерисовки, которая называется paint(). Функция рисования линии drawLine() не содержит объект пера, как в соответствующей функции DrawLine() библиотеки .NET Framework. Цвет пера устанавливается с помощью свойства setColor(). Отлично от программы языка C# реализуется и обработка события мыши, в соответствии с одним из вариантов, изложенных в разделе 10.5. Вместо функции Invalidate() языка C# применена функция repaint(). Эти функции инициируют появление события Paint. Использованию различных классов позволило их импортирование с помощью

import java.awt.*;

import java.awt.event.*;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]