中国程序员联盟 正在重新改版中ing 不便之处还请见谅 改版后将内容涉及java delphi .net php
 
  首页 | 数据库开发 | 网络通讯 | 多线程 | 多媒体开发 | 图像处理 | 程序人生 | 系统函数 | 控件开发 | Web服务
 
  当前位置:笨鱼delphi技术网>数据库开发>开发应用>文章内容

delphi 使用Application.ProcessMessages

来源:国外 关于:bill 发布时间:2007-06-23   [收藏] [推荐]

If you are new to Delphi you may be surprised to learn that under certain circumstances none of the event handlers you've coded into your programs will execute when the events occur.

Preposterous? Consider that no more than one section of your program's code can execute at the same time. How, then, can your event handler code execute while your program is performing a lengthy task in a for loop for example?

The Problem

Even if you've never given this any thought, you may nonetheless be familiar with the problem: Your program's user interface is unresponsive during long executions. It appears that the application has died. Your program's main window turns white. The application is stuck in never-never land until lengthy tasks finish.

What can you do to make your application function normally as you execute a lengthy task?

The Solution

A simple solution is Application.ProcessMessages. Application.ProcessMessages is a command that interrupts the execution of an application so that it can respond to events. Specifically, Application.ProcessMessages reads through the messages that Windows has accumulated for your program and selectively executes those parts of your program designed to respond to each message. Short of you calling them directly, this is the only way your event handlers will ever execute.

Using Application.ProcessMessages

Using Application.ProcessMessages is easy, but you'll need to know a little about the Application variable to use it. The Application variable is declared in Delphi's Forms unit. Here is the declaration:

var
  Application: TApplication;

When a Delphi program starts, an instance of TApplication is created. The public variable Application points to this instance. You can therefore make a call to Application.ProcessMessages in any unit that includes Forms in one of its uses clauses.

uses
  Forms, ...

Whenever you code a loop (while, for, repeat/until) into your program, place a call to Application.ProcessMessages somewhere inside the loop. This will allow your application to repaint, minimize, maximize, resize, or respond to messages in some other way while your loop executes. The following lines of code illustrate the idea:

for I := 1 to 1000 do
begin
  ....
  ....
  ....
  Application.ProcessMessages;
end;

An Example<

Let's look at a simple example. This example loops through over 900 records with a progress bar and a label to display progress. To create the example yourself, start a new project and drop the following components onto the form:

    TTable
    TButton
    TProgressBar
    TLabel

Click on the TTable component and set the DatabaseName property in the object inspector to DBDEMOS and the TableName property to ITEMS.DB. Then double click on the TButton component and code the OnClick event as follows:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ProgressBar1.Max := Table1.RecordCount;
  ProgressBar1.Position := 0;
  Table1.First;
  while not Table1.EOF do
  begin
    Sleep(50);  // Just to slow this down.
    ProgressBar1.Position := ProgressBar1.Position + 1;
    Label1.Caption := 'Record ' + IntToStr(ProgressBar1.Position);
    Table1.Next;
   end;
end;

Run the application and click the button. While the button's event handler is executing, notice that you cannot move the window. Placing another window on top causes your program's window to turn white. The caption of LabeL1 does not change.

Now add a call to Application.ProcessMessages to the button's OnClick event handler. The event handler should now look like this:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ProgressBar1.Max := Table1.RecordCount;
  ProgressBar1.Position := 0;
  Table1.First;
  while not Table1.EOF do
  begin
    Sleep(50);  // Just to slow this down.
    ProgressBar1.Position := ProgressBar1.Position + 1;
    Label1.Caption := 'Record ' + IntToStr(ProgressBar1.Position);
    Application.ProcessMessages;
    Table1.Next;
  end;
end;

Run the application again and click the button. This time notice that you can move the window. Repaint works, and the label is changing!

Everything is working great. Or is it? Where ProcessMessages is called, be aware that all events will be processed, even events that you may not want to have processed. It's up to you to protect your application from the user. Run the application again. Click the button. Wait a few seconds. Click the button again. Notice what has happened. The function started over again.

To prevent this unwanted effect, disable the controls that may cause problems. Let's add a few lines of code to disable and enable the button:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ProgressBar1.Max := Table1.RecordCount;
  ProgressBar1.Position := 0;
  Button1.Enabled := False;
  try
    Table1.First;
    while not Table1.EOF do
    begin
      Sleep(50);  // Just to slow this down.
      ProgressBar1.Position := ProgressBar1.Position + 1;
      Label1.Caption := 'Record ' + IntToStr(ProgressBar1.Position);
      Application.ProcessMessages;
      Table1.Next;
    end;
  finally
    Button1.Enabled := True;
  end;
end;

You should now know enough about Application.ProcessMessages to use it in any Delphi program you write.


[浏览: 次]   
上一篇:delphi Lessons in Good Programming   下一篇:delphi hint
[收藏] [推荐] [返回顶部] [打印本页] [关闭窗口]  
    评论加载中…
google adsense热点文章
·delphi Delphi_三谈多态——善用virtua
·delphi 条形码处理
·delphi Delphi_三层开发基本概念介绍
·delphi 汉字转拼音码(上)
·delphi Olevariant
·delphi CS构架下的客户端自动更新程序
·delphi 在Dephi中使用TStream读写数据
·delphi 汉字转拼音码(下)
·delphi delphi处理流
·delphi 关于使用COM对象的方法
·delphi MTS组件——从理论到实践
·delphi 汉字转拼音码(中3)
     delphi技术网 | firefox 下载 | Avant Browser下载 | dedecms 技术网 | drupal 爱好者 | php 技术网
  Copyright@www.delphichm.com,2006-2009.All Rights Reserved.
 
程序员联盟 | delphi Java .net|QQ:707102932