В данной статье мы рассмотрим проблему, связанную с использованием цикла while в Delphi 7 для непрерывного рисования на экране. Мы увидим, что при определенных условиях использование цикла while может привести к тому, что программа перестанет отвечать. Мы также рассмотрим решение этой проблемы, которое заключается в использовании компонента TTimer для непрерывного рисования.
Оригинальный вопрос
Я использую Delphi 7 и пишу программу, которая должна непрерывно рисовать на экране. В настоящее время в программе не рисуется ничего важного, но это является необходимым условием для программы в будущем. Однако, когда я помещаю процедуру для рисования экрана в цикл while, который можно остановить только нажатием любой кнопки, программа перестает отвечать полностью. Я не понимаю, почему это происходит. Разве как только цикл while может быть прерван, программа должна продолжать работать нормально? Вот исходный код:
unit DD04f1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TeCanvas, ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure Image1OnCreate();
procedure ScreenRender();
procedure OnCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
IsDone : Boolean;
implementation
{$R *.dfm}
procedure TForm1.OnCreate(Sender: TObject);
begin
IsDone := False;
end;
procedure TForm1.Image1OnCreate ();
var
Count:Integer;
begin
image1.canvas.Create();
image1.canvas.Pen.Color:=clBlack;
image1.canvas.rectangle(0,0,640,480);
image1.canvas.Pen.Color:=$ed630e; //bgr instead of rgb
Count:=0;
While (Count < 640) do
begin
image1.Canvas.moveto(Count,0);
image1.Canvas.LineTo(Count,480);
Count:=Count+1;
end;
end;
procedure TForm1.ScreenRender();
var
Count : Integer;
begin
Count:=0;
While(Count<640) do
begin
image1.Canvas.moveto(Count,0);
image1.Canvas.LineTo(Count,480);
Count:=Count+1;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Image1OnCreate();
Button1.Visible := False;
While(IsDone = False) do
begin
ScreenRender();
end;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
IsDone := True;
end;
end.
Альтернативный ответ
Я использую Delphi 7 и пишу программу, которая должна непрерывно рисовать на экране. В настоящее время в программе не рисуется ничего важного, но это является необходимым условием для программы в будущем. Однако, когда я помещаю процедуру для рисования экрана в цикл while, который можно остановить только нажатием любой кнопки, программа перестает отвечать полностью. Я не понимаю, почему это происходит. Разве как только цикл while может быть прерван, программа должна продолжать работать нормально? Вот исходный код:
unit DD04f1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TeCanvas, ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure Image1OnCreate();
procedure ScreenRender();
procedure OnCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
IsDone : Boolean;
implementation
{$R *.dfm}
procedure TForm1.OnCreate(Sender: TObject);
begin
IsDone := False;
end;
procedure TForm1.Image1OnCreate ();
var
Count:Integer;
begin
image1.canvas.Create();
image1.canvas.Pen.Color:=clBlack;
image1.canvas.rectangle(0,0,640,480);
image1.canvas.Pen.Color:=$ed630e; //bgr instead of rgb
Count:=0;
While (Count < 640) do
begin
image1.Canvas.moveto(Count,0);
image1.Canvas.LineTo(Count,480);
Count:=Count+1;
end;
end;
procedure TForm1.ScreenRender();
var
Count : Integer;
begin
Count:=0;
While(Count<640) do
begin
image1.Canvas.moveto(Count,0);
image1.Canvas.LineTo(Count,480);
Count:=Count+1;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Image1OnCreate();
Button1.Visible := False;
While(IsDone = False) do
begin
ScreenRender();
end;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
IsDone := True;
end;
end.
Подтвержденный ответ
В приведенном выше коде цикл while в процедуре Button1Click не может быть прерван, даже если переменная IsDone установлена в True в процедуре FormKeyDown. Это происходит потому, что процедура FormKeyDown не вызывается внутри цикла while в процедуре Button1Click. Чтобы решить эту проблему, можно использовать компонент TTimer для непрерывного рисования на экране.
Для этого можно добавить компонент TTimer на форму и установить его интервал в значение, соответствующее частоте кадров, например, 30 миллисекунд. Затем можно добавить обработчик события OnTimer для компонента TTimer, в котором будет вызываться процедура ScreenRender для рисования на экране. При этом переменная IsDone больше не понадобится, так как рисование будет происходить автоматически при каждом срабатывании таймера.
Ниже приведен пример кода, демонстрирующий это решение:
unit DD04f1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TeCanvas, ExtCtrls, Timer;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
Timer1: TTimer;
procedure Image1OnCreate();
procedure ScreenRender();
procedure OnCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.OnCreate(Sender: TObject);
begin
Timer1.Enabled := True;
Timer1.Interval := 30;
end;
procedure TForm1.Image1OnCreate ();
var
Count:Integer;
begin
image1.canvas.Create();
image1.canvas.Pen.Color:=clBlack;
image1.canvas.rectangle(0,0,640,480);
image1.canvas.Pen.Color:=$ed630e; //bgr instead of rgb
Count:=0;
While (Count < 640) do
begin
image1.Canvas.moveto(Count,0);
image1.Canvas.LineTo(Count,480);
Count:=Count+1;
end;
end;
procedure TForm1.ScreenRender();
var
Count : Integer;
begin
Count:=0;
While(Count<640) do
begin
image1.Canvas.moveto(Count,0);
image1.Canvas.LineTo(Count,480);
Count:=Count+1;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Image1OnCreate();
Button1.Visible := False;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Timer1.Enabled := False;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
ScreenRender();
end;
end.
В этом примере цикл while в процедуре ScreenRender больше не нужен, так как рисование происходит автоматически при каждом срабатывании таймера. Процедура FormKeyDown используется для остановки таймера при нажатии любой кнопки. При этом программа продолжает отвечать на другие события, такие как нажатие кнопок, перемещение мыши и т.д.
Заключение
В данной статье мы рассмотрели проблему, связанную с использованием цикла while в Delphi 7 для непрерывного рисования на экране. Мы увидели, что при определенных условиях использование цикла while может привести к тому, что программа перестанет отвечать. Мы также рассмотрели решение этой проблемы, которое заключается в использовании компонента TTimer для непрерывного рисования. Пример кода, приведенный в статье, демонстрирует, как это решение может быть реализовано в программе.
В данной статье рассматривается проблема, связанная с использованием цикла while в Delphi 7 для непрерывного рисования на экране, которая может привести к тому, что программа перестанет отвечать. В качестве решения предлагается использовать компонент TTim
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.