【发布时间】:2017-11-09 23:52:44
【问题描述】:
我正在使用 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.
【问题讨论】:
-
您不允许处理 Windows 消息。你的代码有缺陷。使用调试器单步执行并找出原因。如所写,在循环运行时它不会响应任何内容,包括尝试移动表单、调整其大小或任何其他与 UI 相关的内容。我什至不确定它是如何获得消息以按照现在的方式停止循环。
-
如果是我,我会删除这篇文章,重新考虑你正在尝试做的事情让你认为你需要这个循环,然后发布一个关于如何在没有这个循环的情况下做这件事的新问题循环。您在这里没有解释为什么您认为必须不断地在屏幕上绘制。我可以说,只要解决方案是 Application.ProcessMessages,你就做错了。
-
无论如何,如果您需要“不断地”绘制图像,您应该使用
OnPaint事件或WM_PAINT消息,并且仅在 Windows 告诉您它已准备好时才绘制你来画画。但既然你是在TImage而不是控制画布上绘画,我真的不知道你想做什么。 -
您最好先了解普通的 Windows API 本身,因为 Delphi 的 VCL 框架高度基于它 - 包括尤其是 Windows 消息系统。长话短说,只要您运行任何类型的循环,Windows 就无法处理消息队列。消息队列负责处理用户输入和绘制到窗口。
-
@Jerry: 是的,我更专注于指出似乎是 XY 问题。这段代码设计得很糟糕,提出的问题是完全错误的。问题应该是首先询问进行连续绘图的正确方法,而不是如何解决循环问题。
标签: delphi while-loop crash pascal