线程中当然可以处理消息的!!! procedure TMyThread.Execute; var i : integer; begin inherited; for i:= 0 to 10000 do begin step := i; if step = 5000 then begin SendMessage(Form1.Handle,WM_SYSCOMMAND,SC_MINIMIZE,0); end; synchronize(draw); end;end; 你就用消息来处理吧!
感谢leeky及各位,我还有些疑惑: 1,我用在线程中显示form的,测试代码如下: unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type passadmit = class(Tthread) protected procedure Execute;override; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementationuses Unit2;{$R *.dfm}procedure passadmit.Execute; begin Form2:=Tform2.create(nil); Form2.showmodal; end;procedure TForm1.Button1Click(Sender: TObject); begin passadmit.create(false); end;end. 调试执行时,出错为canvas does not allow draw 不知是否是我的delphi或系统有问题,delphi6,win20002、看来发消息是一个好的解决办法,但我要传递一些参数,和一幅图像,谁能给个消息传递的例子吗?我还没怎么用过那一块。
关于消息,哪天有空再试试. :) 确实还是可以, synchronize(progress); if PeekMessage(myMsg,0,0,0,PM_REMOVE) then begin if (myMsg.message = WM_QUIT) then Terminate; end;我还想做进一步……
关于消息,哪天有空再试试. :) 确实还是可以, synchronize(progress); if PeekMessage(myMsg,0,0,0,PM_REMOVE) then begin if (myMsg.message = WM_QUIT) then Terminate; end;我还想做进一步……
这个是根据你的代码改了一下,不太准确 const CM_FORMSHOW = WM_USER + $0100; type passadmit = class(Tthread) FHandle: THandle; FImage : TImage; protected procedure Execute;override; constructor Create(Handle: THandle;image: TImage); end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private procedure CMFORMSHOW(var msg: TMsg);message CM_FORMSHOW; { Private declarations } public { Public declarations } end;var Form1: TForm1;implementationuses Unit2;{$R *.dfm} constructor passadmit.Create(Handle: THandle;image: TImage); begin FHandle := Handle; Fimage := image; end;procedure passadmit.Execute; begin if ... then begin SendMessage(FHandle,CM_FORMSHOW,0,0); end; end;procedure TForm1.Button1Click(Sender: TObject); begin passadmit.create(Handle,Image); end;procedure TForm1.CMFORMSHOW(var msg: TMsg); begin // Form2.ShowModal; end;end.delphi的线程对象真的不爽
你还可以这样来做:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;type TForm1 = class(TForm) Edit1: TEdit; Image1: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;TMyThread = class(TThread) private child : TComponent; step : integer; FormThread : TForm1; public procedure draw; constructor Create(parent : TComponent); destructor destroy; procedure Execute; override; end;var Form1: TForm1; implementation{$R *.dfm}{ TMyThread }constructor TMyThread.Create(parent: TComponent); begin child := parent; inherited Create(false); end;destructor TMyThread.destroy; begin if FormThread <> nil then FreeAndNil(FormThread); end;procedure TMyThread.draw; begin if (child is TEdit) then begin (child as TEdit).Text := inttostr(step); end else if(child is TImage) then begin (child as TImage).Canvas.Brush.Color := TColor(step*4); (child as TImage).Canvas.FillRect(rect(0,0,100,100)); end; if Step = 5000 then begin FormThread :=TForm1.Create(nil); FormThread.Show; end; end;procedure TMyThread.Execute; var i : integer; begin inherited; for i:= 0 to 10000 do begin step := i; if step = 5000 then begin // SendMessage(Form1.Handle,WM_SYSCOMMAND,SC_MINIMIZE,0); end; synchronize(draw); end;end; procedure TForm1.Button1Click(Sender: TObject); begin TMythread.Create(Edit1); TMythread.Create(image1);end;end. 虽然这里面还有个step的同步问题,但足可以解决你的问题!
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type passadmit = class(Tthread) private FrmThread : TForm2; protected procedure Execute;override; public procedure draw; destructor destroy; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementationuses Unit2;{$R *.dfm} destructor passadmit.destroy; begin if frmThread <> nil then FreeAndNil(frmThread); end; procedure passadmit.draw; begin if frmThread <> nil then FreeAndNil(frmThread); frmThread:=Tform2.create(nil); frmThread.show;//showmodal 会阻塞线程; end; procedure passadmit.Execute; var i : integer; begin for i:=0 to 10000 do begin if i = 5000 then sychronize(draw); do sth; end; end;procedure TForm1.Button1Click(Sender: TObject); begin passadmit.create(false); end;end.
线程中操作Delphi控件,容易出问题。
线程一般都没有form的,因为它没有消息循环,处理不了form的消息。
你想说啥?想好了说。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Image1: TImage;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;TMyThread = class(TThread)
private
child : TComponent;
step : integer; public
procedure draw;
constructor Create(parent : TComponent);
procedure Execute; override; end;var
Form1: TForm1;
implementation{$R *.dfm}{ TMyThread }constructor TMyThread.Create(parent: TComponent);
begin
child := parent;
inherited Create(false);
end;procedure TMyThread.draw;
begin
if (child is TEdit) then
begin
(child as TEdit).Text := inttostr(step);
end
else if(child is TImage) then
begin
(child as TImage).Canvas.Brush.Color := TColor(step*4);
(child as TImage).Canvas.FillRect(rect(0,0,100,100));
end;
end;procedure TMyThread.Execute;
var
i : integer;
begin
inherited;
for i:= 0 to 10000 do
begin
step := i;
synchronize(draw);
end;
if Terminated then Exit;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TMythread.Create(Edit1);
TMythread.Create(image1);end;end.
各位清除了吗?谢谢,或者给我一个其它的解决办法吧
当然在线程的代码中也可以这么写 Form3.showmodal?(你得包含这窗体的单元)
线程单元中是不能处理消息的.
我做的工控程序就有很多线程,其中一个为串口单元.
刚才我在串口单元的串口线程Execute方法里调用了
FormInf.ShowModal;
是可行的.
当form create时,就出错"canvas can not allow drawing".
线程满足条件后给主Form发一个消息,然后在主Form中处理
这个消息就行了。
Auto-create forms里而不是Available forms内如何?
procedure TMyThread.Execute;
var
i : integer;
begin
inherited;
for i:= 0 to 10000 do
begin
step := i;
if step = 5000 then
begin
SendMessage(Form1.Handle,WM_SYSCOMMAND,SC_MINIMIZE,0);
end;
synchronize(draw);
end;end;
你就用消息来处理吧!
1,我用在线程中显示form的,测试代码如下:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
passadmit = class(Tthread)
protected
procedure Execute;override;
end; TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementationuses Unit2;{$R *.dfm}procedure passadmit.Execute;
begin
Form2:=Tform2.create(nil);
Form2.showmodal;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
passadmit.create(false);
end;end.
调试执行时,出错为canvas does not allow draw
不知是否是我的delphi或系统有问题,delphi6,win20002、看来发消息是一个好的解决办法,但我要传递一些参数,和一幅图像,谁能给个消息传递的例子吗?我还没怎么用过那一块。
:)
确实还是可以,
synchronize(progress);
if PeekMessage(myMsg,0,0,0,PM_REMOVE) then
begin
if (myMsg.message = WM_QUIT) then
Terminate;
end;我还想做进一步……
:)
确实还是可以,
synchronize(progress);
if PeekMessage(myMsg,0,0,0,PM_REMOVE) then
begin
if (myMsg.message = WM_QUIT) then
Terminate;
end;我还想做进一步……
而是VCL在线程中是危险的,必须使用同步技术,
实际上当你创建窗体时,canvas 被Lock住了,此时是不允许你画的!
const CM_FORMSHOW = WM_USER + $0100;
type
passadmit = class(Tthread)
FHandle: THandle;
FImage : TImage;
protected
procedure Execute;override;
constructor Create(Handle: THandle;image: TImage);
end; TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure CMFORMSHOW(var msg: TMsg);message CM_FORMSHOW;
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementationuses Unit2;{$R *.dfm}
constructor passadmit.Create(Handle: THandle;image: TImage);
begin
FHandle := Handle;
Fimage := image;
end;procedure passadmit.Execute;
begin
if ... then begin
SendMessage(FHandle,CM_FORMSHOW,0,0);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
passadmit.create(Handle,Image);
end;procedure TForm1.CMFORMSHOW(var msg: TMsg);
begin
//
Form2.ShowModal;
end;end.delphi的线程对象真的不爽
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;type
TForm1 = class(TForm)
Edit1: TEdit;
Image1: TImage;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;TMyThread = class(TThread)
private
child : TComponent;
step : integer;
FormThread : TForm1; public
procedure draw;
constructor Create(parent : TComponent);
destructor destroy;
procedure Execute; override; end;var
Form1: TForm1;
implementation{$R *.dfm}{ TMyThread }constructor TMyThread.Create(parent: TComponent);
begin
child := parent;
inherited Create(false);
end;destructor TMyThread.destroy;
begin
if FormThread <> nil then
FreeAndNil(FormThread);
end;procedure TMyThread.draw;
begin
if (child is TEdit) then
begin
(child as TEdit).Text := inttostr(step);
end
else if(child is TImage) then
begin
(child as TImage).Canvas.Brush.Color := TColor(step*4);
(child as TImage).Canvas.FillRect(rect(0,0,100,100));
end;
if Step = 5000 then
begin
FormThread :=TForm1.Create(nil);
FormThread.Show;
end;
end;procedure TMyThread.Execute;
var
i : integer;
begin
inherited;
for i:= 0 to 10000 do
begin
step := i;
if step = 5000 then
begin
// SendMessage(Form1.Handle,WM_SYSCOMMAND,SC_MINIMIZE,0);
end;
synchronize(draw);
end;end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TMythread.Create(Edit1);
TMythread.Create(image1);end;end.
虽然这里面还有个step的同步问题,但足可以解决你的问题!
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
passadmit = class(Tthread)
private
FrmThread : TForm2;
protected
procedure Execute;override;
public
procedure draw;
destructor destroy;
end; TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementationuses Unit2;{$R *.dfm}
destructor passadmit.destroy;
begin
if frmThread <> nil then
FreeAndNil(frmThread);
end;
procedure passadmit.draw;
begin
if frmThread <> nil then
FreeAndNil(frmThread);
frmThread:=Tform2.create(nil);
frmThread.show;//showmodal 会阻塞线程;
end;
procedure passadmit.Execute;
var
i : integer;
begin
for i:=0 to 10000 do
begin
if i = 5000 then
sychronize(draw);
do sth;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
passadmit.create(false);
end;end.
有什么好吃的,可惜我不在深圳,要不, 你打个package, Eat-Mail过来!
发消息,用全局变量吧,或者用Mutex, Event等等之类的,不过不知道Delphi封装了没有,
否则还得用SDK!
begin
if i = 5000 then
sychronize(draw);
do sth;
end;
循环是不是同步必须的要的?
pathe(睡斛) 你在哪?
这只是个例子,要不然线程一下子就结束了!
我只不过让他多消耗点时间!
我明白你的意思,实际上你是开一个线程来监视串口数据,
如果满足条件就调用sychronize(draw);
而在SetTimer所设置的处理函数内判断myCommEvent,为真则你的显示窗体。
而在SetTimer所设置的处理函数内判断myCommEvent,为真则你的显示窗体。
点,我先加分,再给分。