Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Решение проблемы с циклом while в Delphi 7: использование TTimer для непрерывного рисования

Delphi , Синтаксис , Циклы

В данной статье мы рассмотрим проблему, связанную с использованием цикла 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




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


:: Главная :: Циклы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-16 00:45:41/0.0031921863555908/0