События формы OnPaint и OnResize

Программный код, позволяющий рисовать в окне, можно запускать по кнопке. Также у окна есть события, которые имеют специальное назначение, такие как OnPaint и OnResize.

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

Например, проделайте такое простое упражнение:

1. На событие OnPaint формы навесим обработчик, который рисует в окне какую-нибудь простую фигуру, например, окружность.

2. Запустим программу на выполнение

3. Закроем окно приложения любым другим окном

4. Снова сделаем окно нашего приложения окном переднего плана

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

Событие OnResize имеет место всякий раз, когда изменяются размеры окна. Для того чтобы узнать, как изменились размеры необходимо воспользоваться событием OnCanResize. Событию передаются переменные:

Sender – указатель на объект источник события;

NewWidth – содержит новое значение ширины объекта;

NewHeight – содержит новое значение высоты объекта;

Resize – содержит true, если была сделана попытка изменить размеры объекта и false в противном случае.

Например, проделаем такое простое упражнение: нарисуем фигуру в окне, например, прямоугольник. Каждый раз при изменении размеров окна, размеры прямоугольника должны изменяться пропорционально растяжению окна по горизонтали и вертикали. Внешний вид окна:

События формы OnPaint и OnResize - student2.ru

Программный код может иметь следующий вид:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

procedure FormCreate(Sender: TObject);

procedure FormCanResize(Sender: TObject; var NewWidth,

NewHeight: Integer; var Resize: Boolean);

procedure FormResize(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

var

hr,wr:integer; { высота и ширина прямоугольника}

hf,wf:integer; { высота и ширина формы }

x0,y0:integer; { координаты левого верхнего угла прямоугольника}

kx,ky:real; { коэффициенты пропорциональности по x и y}

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

{ задание начальных значений переменным }

x0:=50; y0:=30;

hr:=150; wr:=170;

kx:=hr/width; ky:=wr/height;

end;

procedure TForm1.FormCanResize(Sender: TObject; var NewWidth,

NewHeight: Integer; var Resize: Boolean);

begin

{ код, позволяет определить новые размеры формы}

if resize then

begin

wr:=round(kx*NewWidth);

hr:=round(ky*NewHeight);

with canvas do

begin

// стереть прямоугольник

pen.Color:=color;

brush.Color:=color;

rectangle(x0,y0,x0+wf,y0+hf);

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

brush.Color:=clBlue;

rectangle(x0,y0,x0+wr,y0+hr);

end;

end;

end;

procedure TForm1.FormResize(Sender: TObject);

begin

{ сохраняем старые размеры формы в переменных wf и hg }

wf:=width; hf:=height;

end;

end.

Задания для самостоятельной работы

  1. Hарисовать на белом экране прямоугольник с границей красного цвета и зелены­ми диагоналями.
  2. Hарисовать светофор
  3. Hарисовать российский флаг, японский флаг
  4. Hарисовать елочку зеленого цвета с желтой границей, как показано на рисунке:

События формы OnPaint и OnResize - student2.ru

  1. Hарисовать снеговика
  2. Нарисовать олимпийские кольца.
  3. Изобразить домик в центре экрана, размеры произвольные, крыша – красная, стены – синие, двери, окна – зеленые. Внизу сделать подпись.
  4. Hарисовать радугу на голубом фоне.
  5. Hарисовать схему изображения городов, координаты которых вводятся с кла­виатуры, причем размер кружочка, обозначающего город, зависит от численности населения города.

Занятие 7. Циклы

Часто бывает необходимо однотипные операции повторить несколько раз, например, нарисовать несколько разноцветных точек на экране, рисовать концентрические окружности на экране до тех пор, пока они не выйдут за границы экрана, посчитать сумму ряда чисел и т. д. Для решения подобных задач используют циклический алгоритм, цикл (повтор). В языке Pascal используется 3 вида циклов:

1. Цикл со счетчиком: for

2. Цикл с предусловием: while

3. Цикл с постусловием: repeat.. until.

Цикл со счетчиком: for

Цикл for используется, если известно число повторов (шагов) цикла. В таких циклах имеется переменная целого типа, которая называется счетчиком цикла. Оператор цикла состоит из двух частей:

- в первой, называемой заголовком, указывается переменная – счетчик цикла, задается ее начальное и конечное значения, а также шаг изменения.

- во второй части, называемой тело цикла, задаются операторы, которые будут повторяться заданное счетчиком число раз.

Блок-схема цикла изображена на рисунке:

 
  События формы OnPaint и OnResize - student2.ru

Операторы тела цикла выполняются, пока значение счетчика цикла меньше конечного значения. Значение счетчика цикла автоматически увеличивается при каждом очередном проходе цикла на величину шага. Не рекомендуется в теле цикла изменять значение счетчика цикла.

Синтаксис оператора for имеет следующий вид:

For <счетчик>:=<начальное значение> {TO | DOWNTO} <конечное значение > Do

<оператор>;

Если перевести на русский язык все английские слова этого оператора, то эта фраза будет означать следующее: для счетчика от начального значения до конечного значения делать операторы цикла.

При этом <счетчик> всегда переменная типа integer;

в фигурных скобках указывается выбор из двух вариантов:

TO – обозначает, что шаг изменения счетчика равен 1;

DOWNTO – обозначает, что шаг изменения счетчика равен –1(минус 1).

<оператор> – любой, чаще всего составной оператор.

Если в теле цикла должны выполняться несколько операторов, они должны оформляться в виде так называемого составного оператора, т.е. заключаться в операторные скобки begin.. end.

Пример1. Посчитать сумму всех чисел от 1 до 100:

Var

sum, i: integer;

begin

sum:=0;

for i: = 1 to 100 do sum := sum + i;

end;

Пример 2. нарисовать 20 концентрических окружностей, исходящих из центра экрана, радиус каждой следующей окружности на 10 больше предыдущей.

procedure TForm1.FormPaint(Sender: TObject);

var i:integer;

x0,y0:integer;

begin

x0:=Width div 2 - 5;

y0:= Height div 2 - 5;

with canvas do

begin

pen.Color:=clRed;

pen.Width:=3;

{ делаем окружности прозрачными }

brush.Style:=bsClear;

for i:=1 to 20 do

begin

ellipse(x0,y0,x0+i*10,y0+i*10);

x0:=x0 - 5; y0:= y0 - 5;

end;

end;

end;

На рисунке изображено то, что получается в результате выполнения этого кода.

События формы OnPaint и OnResize - student2.ru

Цикл с предусловием: while

Циклы с предусловием используются тогда, когда выполнение операторов тела цикла зависит от некоторого условия, которое проверяется перед очередным шагом цикла.

Блок-схема цикла приведена на рисунке.

 
  События формы OnPaint и OnResize - student2.ru

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

При использовании цикла с предусловием необходимо понимать, что:

1. значение условия выполнения цикла должно быть определено до начала цикла;

2. если условие входа в цикл ложно, то происходит выход из цикла;

3. хотя бы один из операторов тела цикла должен влиять на условие выполнения цикла, иначе цикл будет повторяться бесконечное число раз;

4. цикл может не выполниться ни разу, если условие входа в цикл ложно.

Синтаксис оператора, реализующего цикл с предусловием приведен ниже:

While <условие> do <оператор>;

Если перевести на русский язык все английские слова этого предложения, то получится следующая понятная русская фраза: до тех пор, пока условие=истина делать операторы. При этом:

Условие – это логическое выражение, которое может принимать значение либо истина (true), либо ложь (false).

Оператор – это либо одиночный, либо составной оператор.

Пример 1. Посчитать сумму ряда чисел: 1+1/2+1/3+…1/n , до тех пор, пока n<=100.

var

i:integer;

sum:real;

begin

sum:=0; i:=1;

while i<=100 do

begin

sum:=sum+1/i;

i:=i+1;

end;

label1.Caption:='sum='+FloatToStr(sum);

Пример 2. Рисовать концентрические окружности в окне, до тех пор, пока они входят в окно.

События формы OnPaint и OnResize - student2.ru

var x0,y0:integer;

sh,i:integer;

begin

sh:=10; {расстояние между окружностями}

{ координаты левого верхнего угла}

x0:=width div 2 - sh; y0:=height div 2 - sh ;

with canvas do

begin

pen.Color:=clGreen;

pen.Width :=5;

{ делаем окружности прозрачными }

brush.Style:=bsClear;

i:=1;

while (x0>0) and (y0>0) and

(x0+2*i*sh<ClientWidth) and (y0+2*i*sh<ClientHeight) do

begin

ellipse(x0,y0,x0+2*sh*i,y0+2*sh*i);

i:=i+1;

x0:=x0-sh;

y0:=y0-sh;

end; { end while }

end; { end with}

end;

Наши рекомендации