报警循环时,如何响应别的事件?(100分)

  • 主题发起人 主题发起人 xuzy888
  • 开始时间 开始时间
X

xuzy888

Unregistered / Unconfirmed
GUEST, unregistred user!
我编了一个循环程序,当报警时,进入一个循环,让报警显示控件(EfRndBtn1)闪动红色并响风鸣声。该警报可以手工清除。问题是,我的清除程序根本未得到执行,请高手看一看错在哪里,该如何改?是否应在循环中加入对事件的检测?又该用什么语句?急!急!急!
[EfRndBtn1是一个圆形的控件,我用来显示警情]
procedure TForm1.Button9Click(Sender: TObject);//报警测试
var
begin
EfRndBtn1.color:=clRed;
flag:=true;
while(flag=true) do begin
EfRndBtn1.visible:=not(EfRndBtn1.visible);
beep
end;
end;

procedure TForm1.EfRndBtn1OnClick(Sender: TObject);//报警清除
begin
flag:=false;
EfRndBtn1.color:=clBlue;
showmessage('21楼火警');
end;
 
程序一直在
while(flag=true) do begin
EfRndBtn1.visible:=not(EfRndBtn1.visible);
beep
end;
中循环,不可能相应别的事件!
解决方法:
两个:
1。使用 TTimer 使用时间,这样可以相应别的事件,如你的EfRndBtn1OnClick
2。程序中使用线程
3。使用别的窗口,警报一响,就 Show 警报Form,千万别ShowModle!
4。在你的

while(flag=true) do begin
EfRndBtn1.visible:=not(EfRndBtn1.visible);
beep ;
Application.ProcessMessages //加入
end;
 
在循环中加入对事件的检测

Application.ProcessMessages

interrupts the execution of an application so that Windows can process the message queue.

procedure ProcessMessages;


Description

Call ProcessMessages to permit Windows to process these messages that are currently in the message queue. ProcessMessages cycles the Windows message loop until it is empty and then returns control to the application.

Note: Neglecting message processing affects only the application calling ProcessMessages, not other applications. In lengthy operations, calling ProcessMessages periodically allows the application to respond to paint and other messages.
Note: ProcessMessages does not allow the application to go idle, whereas HandleMessage does.

ProcessMessages 的响应时间比较久,好像是1秒吧,但是可以修改~
 
1。使用 TTimer 使用时间事件,这样可以相应别的事件,如你的EfRndBtn1OnClick
在 Timer1.OnTimer 中写你的
EfRndBtn1.color:=clRed;
flag:=true;
while(flag=true) do begin
EfRndBtn1.visible:=not(EfRndBtn1.visible);
beep
end;

This example uses two buttons that are long enough to accommodate lengthy captions on a form. When the user clicks the button with the caption Ignore Messages, the code begins to generate a long series of random numbers. If the user tries to resize the form while the handler is running, nothing happens until the handler is finished. When the user clicks the button with the caption Process Messages, more random numbers are generated, but Windows can still respond to a series of mouse events, such as resizing the form.

Note: How quickly these event handlers run depends on the microprocessor of your computer. A message appears on the form informing you when the handler has finished executing.

procedure TForm1.FormCreate(Sender: TObject);

begin
Button1.Caption := 'Ignore Messages';
Button2.Caption := 'Process Messages';

end;

procedure TForm1.Button1Click(Sender: TObject);

var
I, J, X, Y: Word;
begin
I := 0;
J := 0;
while I < 64000 do
begin
Randomize;
while J < 64000 do
begin
Y := Random(J);
Inc(J);
end;
X := Random(I);
Inc(I);
end;
Canvas.TextOut(10, 10, 'The Button1Click handler is finished');

end;

procedure TForm1.Button2Click(Sender: TObject);

var
I, J, X, Y: Word;
begin
I := 0;
J := 0;
while I < 64000 do
begin
Randomize;
while J < 64000 do
begin
Y := Random(J);
Inc(J);
Application.ProcessMessages;
end;
X := Random(I);
Inc(I);
end;
Canvas.TextOut(10, 10, 'The Button2Click handler is finished');

end;
 
用线程!
 
在报警循环里加入APPLICATION。PROCESSMESSAGES就可以了。
即:

while(flag=true) do
begin
EfRndBtn1.visible:=not(EfRndBtn1.visible);
beepend;
Application.ProcessMessages;
//它的作用就是每到这里,系统就会停下来,看看消息队列里有什么消息
//没有处理的,先处理一下,此时若你清除报警,FLAG就变成FALSE,循环也
//就结束了。
end;
 
用TTimer控件可以解决问题,但是可以用创建一个线程类,再execute中加入事件
,在报警启动时,将相应的线程激活,用线程的最大好处是可以控制其优先级.
 
以上方法都可行,
处理事件是经典方案,
线程干净利落,是我推荐的,
至于定时器,毕竟占用系统资源,响应也有延迟。
 
来迟了,同意 YCK!!!
 
加入 Application.ProcessMessages //
或放在线程中。
 
同意答案。
 
后退
顶部