以下程序在关闭窗口时,总是报"无效的窗口句柄"错误!请高人指点.
unit main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cxLookAndFeelPainters, cxPC, cxControls, StdCtrls, cxButtons,
ImgList, ExtCtrls, Menus, RzStatus, RzTray, cxContainer, cxEdit,
cxTextEdit, cxMemo, DB, DBTables, LMDCustomComponent, LMDClass,
LMDStopWatch;type
Tmain_frm = class(TForm)
cxButton1: TcxButton;
cxButton2: TcxButton;
cxButton3: TcxButton;
cxPageControl1: TcxPageControl;
cxTabSheet1: TcxTabSheet;
cxTabSheet2: TcxTabSheet;
Label1: TLabel;
Label2: TLabel;
ImageList1: TImageList;
RzTrayIcon1: TRzTrayIcon;
RzGlyphStatus1: TRzGlyphStatus;
RzGlyphStatus2: TRzGlyphStatus;
PopupMenu1: TPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
cxMemo1: TcxMemo;
procedure cxButton3Click(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; type
DataSync = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
Memo1:TcxMemo;
constructor create; virtual; { 线程构造器 }
end;
var
main_frm: Tmain_frm;
DS1:DataSync;
implementationuses DM, DSThread;{$R *.dfm}procedure Tmain_frm.cxButton3Click(Sender: TObject);
begin
RzTrayIcon1.MinimizeApp;
end;procedure Tmain_frm.N1Click(Sender: TObject);
begin
RzTrayIcon1.RestoreApp;
end;procedure Tmain_frm.N3Click(Sender: TObject);
begin
Close;
end;procedure Tmain_frm.FormCreate(Sender: TObject);
begin
DS1:=DataSync.create;
end;procedure DataSync.Execute;
var
i:Integer;
begin
{ Place thread code here }
i:=0;
while (not Terminated) and (i<=10000)do
begin
Memo1.Lines.Add('这是第'+IntToStr(i)+'个数据!');
i:=i+1;
end;
end;constructor DataSync.create;
begin
Memo1:=main_frm.cxMemo1;
inherited create(False);
end;procedure Tmain_frm.FormDestroy(Sender: TObject);
begin
DS1.Terminate; { 销毁之前终止线程执行 }
DS1.Destroy;
end;end.
unit main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cxLookAndFeelPainters, cxPC, cxControls, StdCtrls, cxButtons,
ImgList, ExtCtrls, Menus, RzStatus, RzTray, cxContainer, cxEdit,
cxTextEdit, cxMemo, DB, DBTables, LMDCustomComponent, LMDClass,
LMDStopWatch;type
Tmain_frm = class(TForm)
cxButton1: TcxButton;
cxButton2: TcxButton;
cxButton3: TcxButton;
cxPageControl1: TcxPageControl;
cxTabSheet1: TcxTabSheet;
cxTabSheet2: TcxTabSheet;
Label1: TLabel;
Label2: TLabel;
ImageList1: TImageList;
RzTrayIcon1: TRzTrayIcon;
RzGlyphStatus1: TRzGlyphStatus;
RzGlyphStatus2: TRzGlyphStatus;
PopupMenu1: TPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
cxMemo1: TcxMemo;
procedure cxButton3Click(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; type
DataSync = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
Memo1:TcxMemo;
constructor create; virtual; { 线程构造器 }
end;
var
main_frm: Tmain_frm;
DS1:DataSync;
implementationuses DM, DSThread;{$R *.dfm}procedure Tmain_frm.cxButton3Click(Sender: TObject);
begin
RzTrayIcon1.MinimizeApp;
end;procedure Tmain_frm.N1Click(Sender: TObject);
begin
RzTrayIcon1.RestoreApp;
end;procedure Tmain_frm.N3Click(Sender: TObject);
begin
Close;
end;procedure Tmain_frm.FormCreate(Sender: TObject);
begin
DS1:=DataSync.create;
end;procedure DataSync.Execute;
var
i:Integer;
begin
{ Place thread code here }
i:=0;
while (not Terminated) and (i<=10000)do
begin
Memo1.Lines.Add('这是第'+IntToStr(i)+'个数据!');
i:=i+1;
end;
end;constructor DataSync.create;
begin
Memo1:=main_frm.cxMemo1;
inherited create(False);
end;procedure Tmain_frm.FormDestroy(Sender: TObject);
begin
DS1.Terminate; { 销毁之前终止线程执行 }
DS1.Destroy;
end;end.
begin
FTerminated := True;
end;
所以线程仍然必须继续执行到正常结束后才行,而不是立即终止线程,这一点要注意。
在这里说一点题外话:很多人都问过我,如何才能“立即”终止线程(当然是指用TThread创建的线程)。结果当然是不行!终止线程的唯一办法就是让 Execute方法执行完毕,所以一般来说,要让你的线程能够尽快终止,必须在Execute方法中在较短的时间内不断地检查Terminated标志,以便能及时地退出。这是设计线程代码的一个很重要的原则!
WaitForSingleObject(DS1.Handle, 50);
FreeAndNil(DS1);
http://topic.csdn.net/u/20080819/20/a1d3ca92-ca16-4f02-8a4b-8a236d5c399f.html