简单多线程如下:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; TClientDataThread = class(TThread)
private
public
TargetList :TStrings;
str:string;
procedure Execute; override;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TClientDataThread.Execute;
begin
targetlist.Add('hello');
str:='hello';
end;procedure TForm1.Button1Click(Sender: TObject);
var
DataThread:TClientDataThread;
begin
DataThread:=TClientDataThread.Create(true);
DataThread.TargetList:=memo1.Lines;
datathread.str:=button1.Caption;//为什么button1.caption不会变?
DataThread.Resume;
end;end.我想问,既然memo1.lines会增加,为什么button1.caption不会变。这里我省略了结束线程等,就不要讨论了,我们只讨论第一次单击button1,为什么它的caption不会变,而memo1的内容会变。
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; TClientDataThread = class(TThread)
private
public
TargetList :TStrings;
str:string;
procedure Execute; override;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TClientDataThread.Execute;
begin
targetlist.Add('hello');
str:='hello';
end;procedure TForm1.Button1Click(Sender: TObject);
var
DataThread:TClientDataThread;
begin
DataThread:=TClientDataThread.Create(true);
DataThread.TargetList:=memo1.Lines;
datathread.str:=button1.Caption;//为什么button1.caption不会变?
DataThread.Resume;
end;end.我想问,既然memo1.lines会增加,为什么button1.caption不会变。这里我省略了结束线程等,就不要讨论了,我们只讨论第一次单击button1,为什么它的caption不会变,而memo1的内容会变。
是不是应该这样?button1.Caption:=datathread.str
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; TClientDataThread = class(TThread)
private
fstr: string;
procedure Setstr(const Value: string);
procedure ChangeCaption;
public
TargetList :TStrings;
property str: string read fstr write Setstr;
procedure Execute; override;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TClientDataThread.Execute;
begin
targetlist.Add('hello');
str:='hello';
end;procedure TClientDataThread.Setstr(const Value: string);
begin
fstr := Value;
Synchronize(ChangeCaption);
end;procedure TClientDataThread.ChangeCaption;
begin
Form1.Caption := fstr;
end;procedure TForm1.Button1Click(Sender: TObject);
var
DataThread:TClientDataThread;
begin
DataThread:=TClientDataThread.Create(true);
DataThread.TargetList:=memo1.Lines;
datathread.str:=button1.Caption;//为什么button1.caption不会变?
DataThread.Resume;
end;end.
你的这个修改也不能让button1的caption变成hello,就算你把
TClientDataThread.ChangeCaption里面的Form1.Caption:= fstr
改成Form1.button1.Caption := fstr
我想它的机制和DataThread.TargetList:=memo1.Lines也不一样吧。按照你的修改,现在str已经是属性了,满足你的话:“button1.Caption并不是一个变量,它实际上是对象的属性,属性不能简单地通过它的地址来修改值,所以你必须采用另一种方法:把datathread.str 也定义成一个属性,通过设置属性的写方法来进行操作。”我想问的是:为什么DataThread.TargetList:=memo1.Lines可以让memo1.lines变化而
datathread.str:=button1.Caption却不可以?lines是memo1的属性,它是一个tstrings,所以定义一个
TargetList :TStrings和它匹配;caption是button1的属性,它是一个string,所以定义一个
str:string和它匹配。两者看起来是一样的,而要它们显示,却要用不同的方法,一个用
DataThread.TargetList:=memo1.Lines,另一个用Synchronize(ChangeCaption)?????
var
DataThread:TClientDataThread;
begin
DataThread:=TClientDataThread.Create(true);
DataThread.TargetList:=memo1.Lines;
{
这里,你的DataThread.TargetList是一个对象引用
} datathread.str:=button1.Caption;//为什么button1.caption不会变?
{
这里,dataThread.str本身是一个字符串副本
这面这句话只是将button1.caption的内容复制到dataThread.str
}
DataThread.Resume;
end;procedure TClientDataThread.Execute;
begin
targetlist.Add('hello');
{
你这里通过对象引用调用Add方法,实际上调用的是Memo.Lines.Add()
所以你看到输出
} str:='hello';
{
你这里只是将datathread.str的内容变成'hello'
和button1.caption没有关系,所以button1.caption不会变
}
end;