我想辅线程退出时,一起关掉给辅线程使用的窗口;窗口可以关掉,但会报“非法句柄”的错(200分)

T

tanxi

Unregistered / Unconfirmed
GUEST, unregistred user!
我想辅线程退出时,一起关掉给辅线程使用的窗口;
窗口可以关掉,但会报“非法句柄”的错
unit viewthread;
interface
{对窗口的定义省略}
procedure newqur(qurnum : integer;
pro :string);
implementation
{$R *.dfm}
type
TAdoqueryTread =class(TThread)
private
FForm:Tqurform;
protected
procedure Execute;override;
public
constructor creat(qurnum : integer;pro:string;
f:Tqurform);virtual;
destructor Destroy;override;
end;

destructor TAdoqueryTread.Destroy;
begin
FForm.Free;
inherited Destroy;
end;
.....
{线程结束时释放内存}
procedure Tqurform.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
action:=cafree;
end;
......
 
你的FForm是怎么创建的?如果不是在程序中动态创建的,应该用close吧,用free不行
 
作以下改动:
FForm.Free;
=> FForm.Release;
你可以看看HELP,RELEASE的好处是很明显的。
 
to resun :我的窗口是动态生成的,只不过我没有把代码在这里对出来;
以下是全部关于辅线程和辅窗口的代码:
unit viewthread;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,main,
StdCtrls, Grids, ValEdit, DBTables, DB, ADODB, ComCtrls;
type
Tqurform = class(TForm)
Label1: TLabel;
Label2: TLabel;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
ADOQuery2: TADOQuery;
ADOQuery1: TADOQuery;
ADOConnection: TADOConnection;
ValueListEditor: TValueListEditor;
Memo: TMemo;
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

procedure newqur(qurnum : integer;
pro :string);
implementation
uses
vsl_rs,field_rs,out_vech_rs;
{$R *.dfm}
type
TAdoqueryTread =class(TThread)
private
FForm:Tqurform;
FADOQuery2: TADOQuery;
FADOQuery1: TADOQuery;
FADOConnection: TADOConnection;
FMemo : TMemo;
Fpro: string;
Fflag :boolean;
procedure runseccess;
procedure runfailled;
protected
procedure Execute;override;
public
constructor creat(qurnum : integer;pro:string;
f:Tqurform);virtual;
destructor Destroy;override;
end;

destructor TAdoqueryTread.Destroy;
begin
FForm.Free;
inherited Destroy;
end;

constructor TAdoqueryTread.creat(qurnum : integer;
pro:string;
f :Tqurform);
begin
inherited Create(true);
FForm :=f ;
FForm.Name:=f.name+inttostr(qurnum);
FADOQuery2:=f.adoquery2;
FADOQuery1:=f.adoquery1;
FADOConnection:=f.adoconnection;
FMemo:=f.memo;
Fpro:=pro;
Fflag:=false;
{根据线程创建时的字符串来调用相应的单元的代码}
FADOConnection.ConnectionString:='Provider=OraOLEDB.Oracle.1;Password=edi;Persist Security Info=True;User ID=edi;Data Source=evctms32';
//尝试连接数据库如果失败可以利用try避免错误
try
FMemo.Lines.Add('正在连接源数据库.....! ');
FADOConnection.Connected:=true;
Fmemo.Lines.Add('源数据库连接.........成功! ');
Fflag:=true;
except
FADOConnection.Connected:=false;
Fmemo.Lines.Add('源数据库连接.........失败! ');
Fflag:=false;
end;
//freeonTerminate:=true;
resume;
end;

procedure TAdoqueryTread.Execute;
var
flag :boolean;
begin

try
if Fpro='vsl' then
if Fflag then
vsl_rs.vsl_wrk_pro(FForm) else
;
if Fpro='field' then
if Fflag then
field_rs.field_wrk_pro(FForm) else
;
if Fpro='out_vech' then
if Fflag then
out_vech_rs.out_vech_stand_pro(FForm) else
;
synchronize(runseccess);
except
synchronize(runfailled);
end;
end;

{当线程调用成功时在主线程显示提示和时间信息}
procedure TAdoqueryTread.runseccess;
begin
main.Form1.Memo1.Lines.Add('调用 '+Fpro+' 线程成功!');
main.Form1.memo1.Lines.Add(Fpro+'结束时间>'+datetostr(now)+' '+timetostr(now));
end;
{当线程调用失败时在主线程显示提示和时间信息}
procedure TAdoqueryTread.runfailled;
begin
main.Form1.Memo1.Lines.Add('调用 '+Fpro+' 线程失败!');
main.Form1.memo1.Lines.Add(Fpro+'结束时间>'+datetostr(now)+' '+timetostr(now));
end;

{线程结束时释放内存}
procedure Tqurform.FormClose(Sender: TObject;
var Action: TCloseAction);
begin

end;

{用于在主线程中调用辅线程}
procedure newqur(qurnum : integer;
pro :string);
var
f :Tqurform;
begin
{创建一个新的线程运行状态窗口}
f:=viewthread.Tqurform.Create(application);
TAdoqueryTread.creat(qurnum ,pro,f);
// TAdoqueryTread.creat(qurnum ,pro,viewthread.Tqurform.Create(application));
end;
end.

to huzzz:
请告述我具体用法
 
destructor TAdoqueryTread.Destroy;
begin
FForm.Release;
//FForm.Free;
inherited Destroy;
end;
 
该问题我已经解决了;是由于我把窗口当变量传给线程后,线程执行结束后将它销掉了。而回到窗口时就没有句柄可被销了。
还是感谢你们,各得100吧
 
顶部