如何定义和响应自定义事件。(100分)

  • 主题发起人 主题发起人 panyongze
  • 开始时间 开始时间
P

panyongze

Unregistered / Unconfirmed
GUEST, unregistred user!
我自定义了一个类,其中有一个函数执行时间比较长。
如何将执行进度反馈给调用者?
执行期间如何刷新页面?

调用单元
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, MyUnit, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
aa:TMyClass;
begin
aa:= TMyClass.Create;
aa.MaxValue:=99999;
aa.MinValue:=-999999;
aa.SaveToMyFile('aaa.txt');
aa.Free;
end;
end.

自定义单元

unit MyUnit;

interface

type

TMyClass = class(TObject)
private
FMaxValue:Integer;
FMinValue:Integer;
FPlan:Integer;
public
procedure SaveToMyFile(OutFileName: String);
property MaxValue: Integer read FMaxValue write FMaxValue default MaxInt;
property MinValue: Integer read FMinValue write FMinValue default -MaxInt;
property Plan: Integer read FPlan;
end;

implementation

uses SysUtils;

procedure TMyClass.SaveToMyFile(OutFileName: String);
var
OutFile: TextFile;
I,J: Integer;
S: String;
begin
AssignFile(OutFile,OutFileName);
ReWrite(OutFile);
J := FMaxValue-FMinValue;
for I := FMinValue to FMaxValue do
begin
S := IntToStr(I);
Writeln(OutFile,S);
FPlan := I*100 Div J
//执行进度
end;
CloseFile(OutFile);
end;
end.
 
用线程应该可以,但这和“如何定义和响应自定义事件”有什么关系呢?
 
for I := FMinValue to FMaxValue do
begin
S := IntToStr(I);
Writeln(OutFile,S);
FPlan := I*100 Div J
//执行进度
Application.processmessages;//new 加上此句就可
end;
 
jqw你回答的是第二问,回答正确。
关键是第一问,如何把执行进度通过ProgressBar1显示出来?
 
//定义事件方法如下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, MyUnit, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
[red]procedure process(Sender : TObject;position,max:integer);[/red]
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

[red]procedure TForm1.process((Sender : TObject;position,max:integer);
begin
progressbar1.max := Max;
ProgressBar1.Position := Position;
Refresh;
end;[/red]

procedure TForm1.Button1Click(Sender: TObject);
var
aa:TMyClass;
begin
aa:= TMyClass.Create;
aa.MaxValue:=99999;
aa.MinValue:=-999999;
[red]aa.OnProcess := process;[/red]
aa.SaveToMyFile('aaa.txt');
aa.Free;
end;
end.

自定义单元

unit MyUnit;

interface

type
[red]TMyprocess = procedure(Sender : TObject;position,max:integer) of object;[/red]

TMyClass = class(TObject)
private
FMaxValue:Integer;
FMinValue:Integer;
FPlan:Integer;
[red]FProcess : TMyProcess;[/red]
public
procedure SaveToMyFile(OutFileName: String);
property MaxValue: Integer read FMaxValue write FMaxValue default MaxInt;
property MinValue: Integer read FMinValue write FMinValue default -MaxInt;
property Plan: Integer read FPlan;
[red]published
property onprocess : TMyProcess read FProcess write FProcess;[/red]
end;

implementation

uses SysUtils;

procedure TMyClass.SaveToMyFile(OutFileName: String);
var
OutFile: TextFile;
I,J: Integer;
S: String;
begin
AssignFile(OutFile,OutFileName);
ReWrite(OutFile);
J := FMaxValue-FMinValue;
for I := FMinValue to FMaxValue do
begin
S := IntToStr(I);
Writeln(OutFile,S);
FPlan := I*100 Div J
//执行进度
[red]if assigned(onprocess) then
onProcess(self,i,j);[/red]
end;
CloseFile(OutFile);
end;
end.
 
zhukewen:
麻烦你测试以下你改过的代码,事件是触发了,可是界面好象死机一样啊。
 
jqw你回答的是第二问,想当然应该正确,实际上自定义单元里不认识Application。
你说如何是好?
 
>>“自定义单元里不认识Application。”
你可以这样,在TForm类中添加一个punlic类型的过程,在该过程中调用Application,
然后在你自定义单元中调用该过程。
 
to panyongze:
如果剩下的事你还搞不定,算我白说了。[:(]
 
哈哈自己解决啦。贴出来共享。

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, MyUnit, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure process(Sender : TObject);
end;

var
Form1: TForm1;
aa:TMyClass;

implementation

{$R *.dfm}

procedure TForm1.process(Sender : TObject);
begin
ProgressBar1.Position := AA.Plan;
Application.processmessages;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
aa:= TMyClass.Create;
aa.MaxValue:=99999;
aa.MinValue:=-999999;
aa.OnProcess := process;
aa.SaveToMyFile('aaa.txt');
aa.Free;
end;

end.




unit MyUnit;

interface

uses Classes;

type

TMyClass = class(TObject)
private
FMaxValue:Integer;
FMinValue:Integer;
FPlan:Integer;
FProcess: TNotifyEvent;
public
procedure SaveToMyFile(OutFileName: String);
property MaxValue: Integer read FMaxValue write FMaxValue default MaxInt;
property MinValue: Integer read FMinValue write FMinValue default -MaxInt;
property Plan: Integer read FPlan;
property onprocess : TNotifyEvent read FProcess write FProcess;
end;

implementation

uses SysUtils;

procedure TMyClass.SaveToMyFile(OutFileName: String);
var
OutFile: TextFile;
I,J,K: Integer;
S: String;
begin
AssignFile(OutFile,OutFileName);
ReWrite(OutFile);
J := FMaxValue-FMinValue;
K := 0;
for I := FMinValue to FMaxValue do
begin
S := IntToStr(I);
Writeln(OutFile,S);
Inc(K);
FPlan := K*100 Div J
//执行进度
if assigned(onprocess) then onProcess(self);
end;
CloseFile(OutFile);
end;

end.
 
zw84611:你的多线程如何搞?
 
天哪,我刚上完课回来,还要我把代码给你写出来吗?晚上吧,我下午还有课。
 
你看这样行吗?
========================================
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls,MyUnit;

type
TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure Process(Sender : TObject);
end;


var
Form1: TForm1;
aa:TMyClass;

implementation

{$R *.DFM}

procedure TForm1.Process(Sender : TObject);
begin
ProgressBar1.Position := AA.Plan;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

aa:= TMyClass.Create;
aa.MaxValue:=99999;
aa.MinValue:=-999999;
aa.OnProcess := process;
aa.SaveToMyFile('aaa.txt');
aa.Free;

end;

end.
==============================================================unit MyUnit;

interface

uses Classes;

type

TMyClass = class(TObject)
private
FMaxValue:Integer;
FMinValue:Integer;
FPlan:Integer;
FProcess: TNotifyEvent;
public
procedure SaveToMyFile(OutFileName: String);
property MaxValue: Integer read FMaxValue write FMaxValue default MaxInt;
property MinValue: Integer read FMinValue write FMinValue default -MaxInt;
property Plan: Integer read FPlan;
property onprocess : TNotifyEvent read FProcess write FProcess;
end;

TMyThread=class(TThread)
public
OutFileName:string;
FMaxValue,FMinValue:integer;
ShowProcess:boolean;
Process: TNotifyEvent;//Procedure(Sender : TObject) of object;
pPlan:^integer;
protected
procedure Execute
override;
procedure OnProcess;
end;

implementation

uses SysUtils;

procedure TMyThread.onProcess;
begin
Process(self);
end;

procedure TMyThread.Execute;
var
OutFile: TextFile;
I,J,K: Integer;
S: String;
begin
AssignFile(OutFile,OutFileName);
ReWrite(OutFile);
J := FMaxValue-FMinValue;
K := 0;
for I := FMinValue to FMaxValue do
begin
S := IntToStr(I);
Writeln(OutFile,S);
Inc(K);
pPlan^ := K*100 Div J
//执行进度
if assigned(process) then Synchronize(OnProcess);
end;
CloseFile(OutFile);
end;

procedure TMyClass.SaveToMyFile(OutFileName: String);
var MyThread:TMyThread;
begin
MyThread:=TMyThread.Create(true);
MyThread.OutFileName := OutFileName;
MyThread.FMaxValue := FMaxValue;
MyThread.FMinValue := FMinValue;
MyThread.pPlan:=@FPlan;
if assigned(onprocess) then MyThread.Process:=OnProcess;
MyThread.Resume;
end;
end.
 
zw84611:
可惜!分分早了,不过没关系,可以另开题给你分。

我对多线程不太了解,你能否讲一讲你用多线程代码的代码有什么优点?
我只看调用者出响应事件时省了一句Application.processmessages;
 
后退
顶部