Помощь - Поиск - Пользователи - Календарь
Полная версия: Наперстки.
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Делфи
sheka
вот начало. посмотрите пожалуйста

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Timer1: TTimer;
Button1: TButton;
Label1: TLabel;
procedure FormPaint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

const
x0=100;
y0=200;
rast=250;

var
Form1: TForm1;
a:integer;
n1,n2,r,xc,k:integer;
var i:integer;

implementation

{$R *.dfm}
procedure stakan(x,y:integer);
var
d:integer;
begin
d:=10;
with Form1.Canvas do
begin
Pen.Mode:=pmNotXor;
pen.Color:=clBlack;
pen.Width:=2;
brush.Color:=clSkyBlue;
Ellipse(x-3*d,y,x+3*d,y+2*d);
MoveTo(x-3*d,y+d);
LineTo(x-5*d,y+d+9*d);
MoveTo(x+3*d,y+d);
LineTo(x+5*d,y+d+9*d);
Arc(x-5*d,y+8*d,x+5*d,y+12*d,x-5*d,y+10*d,x+5*d,y+10*d);
end;
end;

procedure dvizh;
begin
n1:=random(3)+1;
n2:=n1;
while n2=n1 do n2:=random(3)+1;
xc:=x0+round((n1+n2-2)*rast/2);
r:=abs(round((n1-n2)*rast/2));
a:=0;
form1.Button1.Enabled:=false;
form1.Timer1.enabled:=true;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
stakan(x0,y0); stakan(x0+rast,y0); stakan(x0+2*rast,y0);
end;

procedure TForm1.FormCreate(Sender: TObject);

begin
randomize;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
stakan(xc+round(r*cos(a/180*pi)),y0+round(r*sin(a/180*pi)));
stakan(xc-round(r*cos(a/180*pi)),y0-round(r*sin(a/180*pi)));
inc(a,5);
stakan(xc+round(r*cos(a/180*pi)),y0+round(r*sin(a/180*pi)));
stakan(xc-round(r*cos(a/180*pi)),y0-round(r*sin(a/180*pi)));
if a>=180 then
begin
timer1.Enabled:=false;
button1.Enabled:=true;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin // вот этот цикл не работает
for i:=1 to 10 do
begin
dvizh;
label1.Caption:=inttostr(i);
end;
end;

end.

посмотрите что не так, уже все проверил...

Добавлено через 2 мин.
да, забыл. на форму надо поставить таймер - неактивный с задержкой 1, кнопку, и для проверки цикла - лабел.
volvo
Тебе Дельфи предупреждение давала? Почему игнорируешь? Проблем ждешь? smile.gif

procedure TForm1.Button1Click(Sender: TObject);
var i: integer; // Вот тут надо i описывать...
begin // вот этот цикл уже работает
for i:=1 to 10 do
begin
dvizh;
label1.Caption:=inttostr(i);
while timer1.Enabled do // ждем, пока не закончится вращение наперстков
begin
Application.ProcessMessages;
end;
end;
end;
sheka
ну i куда я уже только не совал.smile.gif
а что вот это значит Application.ProcessMessages;?
volvo
А это значит, что надо непросто поставить пустой цикл, и ничего в нем не делать, а еще и обрабатывать сообщения, которые поступают во время его выполнения. Без него у тебя даже сообщение от таймера не будет обрабатываться. Дедлок (deadlock) называется, ты ждешь, пока Timer.Enabled станет равным True, а оно не станет потому что сообщения от таймера не обрабатываются...
sheka
А что делать, если в то время, когда таймер включен, я хочу выйти из программы? (при нажатии на крестик программа ожидает not timer1.Enabled)
volvo
Ну, так вспоминай, что происходит при "нажатии на крестик" smile.gif

Правильно, вызывается событие OnCloseQuery... И если сделать вот такой финт ушами:
type
TForm1 = class(TForm)
// Здесь все, что и было
private
{ Private declarations }
bCloseApp: Boolean; // <-- А вот это - добавили
public
{ Public declarations }
end;

// ...

procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;
bCloseApp := False; // Изначально сбрасываем в False
end;

// При запросе пользователя на закрытие формы - переключаем флаг...
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
bCloseApp := True;
end;

// И самое интересное - это таймер:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if not bCloseApp then // Не просили закрыть форму - работаем
begin
stakan(xc+round(r*cos(a/180*pi)),y0+round(r*sin(a/180*pi)));
stakan(xc-round(r*cos(a/180*pi)),y0-round(r*sin(a/180*pi)));
inc(a,5);
stakan(xc+round(r*cos(a/180*pi)),y0+round(r*sin(a/180*pi)));
stakan(xc-round(r*cos(a/180*pi)),y0-round(r*sin(a/180*pi)));
if a>=180 then
begin
timer1.Enabled:=false;
button1.Enabled:=true;
end;
end
else // А вот это уже другое дело. Стоп, выходим
Timer1.Enabled := False;
end;

, то ничего не будет ждать. Ну, как максимум, закончится текущая отрисовка, и все.
sheka
smile.gif Не ожидал.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.