我在关闭多线程程序之后,系统出错:
1.Exception EOSError in module project1.exe at 0000E3Ae.system error code:1400 无效的窗口句柄.
2.Runtime error 216 at 7C921010以下是我的代码:
unit UMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, Grids, DBGrids, StdCtrls, ExtCtrls,excel2000,OleServer,comObj,
DBGridEh, Unit2;type
TMain = class(TForm)
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
DBGrid1: TDBGridEh;
SaveDialog1: TSaveDialog;
Panel1: TPanel;
Button1: TButton;
OpenDialog1: TOpenDialog;
Button3: TButton;
ADOQuery2: TADOQuery;
Label1: TLabel;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Button2Click(Sender: TObject); private
procedure ThreadDone(Sender:TObject);
{ Private declarations }
public
{ Public declarations }
ExcelToSQL:ImportExcel;
end;var
Main: TMain;implementationuses UDM, Unit1;{$R *.dfm}procedure TMain.Button1Click(Sender: TObject);
var
fname,moldid:string;
excelid:variant;
ColumnCount,sheetcount,i,j,k:integer;
begin
//Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Documents and Settings\Administrator\桌面\6月份外加工费用统计表.xls;Extended Properties=Excel 8.0;Persist Security Info=Falseif (Edit1.Text='') then
begin
MessageDlg('输入的内容为空',mtwarning,[mbOK],0);
exit;
end;
if OpenDialog1.Execute then
fname:=OpenDialog1.FileName
else exit;ExcelToSQL:=ImportExcel.Create(fname);
//ExcelToSQL.Resume;
//ExcelToSQL.OnTerminate:=ThreadDone;
end;procedure TMain.FormCreate(Sender: TObject);
begin
ADOQuery1.Active:=True;
end;procedure TMain.Button3Click(Sender: TObject);
begin
ADOQuery1.Requery();
end;procedure TMain.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9',#8]) then key:=#0;
end;procedure TMain.Button2Click(Sender: TObject);
begin
with TForm1.Create(self) do
Show;
end;procedure TMain.ThreadDone(Sender:TObject);
begin
// showmessage('success');
end;end.unit Unit2;interfaceuses
Classes,ADODB,comobj,excel2000,oleserver,SysUtils;type
ImportExcel = class(TThread)
private
Fullfilename:string;
ADOQuery1:TADOQuery;
k:integer;
procedure GetEditText;
{ Private declarations }
protected
procedure Execute; override;
public
Constructor Create(filename:string);
end;implementationuses UMain,dialogs;{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure ImportExcel.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ ImportExcel }Constructor ImportExcel.Create(filename:string);
begin
Fullfilename:=filename;
Inherited Create(False);
end;procedure ImportExcel.GetEditText;
begin
k:=StrToInt(Main.Edit1.text);
end;procedure ImportExcel.Execute;
var
excelid:variant;
i:integer;
begin
{ Place thread code here }
excelid:=Createoleobject('Excel.Application'); //1、创建连接
excelid.visible:=false;
excelid.workbooks.open(Fullfilename); //2、指定文件
Synchronize(GetEditText);Try
try
ADOQuery1:=TADOQuery.Create(nil);
with ADOQuery1 do
begin
ConnectionString:='Provider=MSDASQL.1;Persist Security Info=True;User ID=wu;Data Source=mjgl';
Close;
SQL.Clear;
SQL.Text:='select * from jgfy';
Open;
end;
for i:=3 to 1000 do //最大行数1000
begin
//判断是否结束
if Trim(Excelid.WorkBooks[1].Worksheets[k].Cells[i,1].Value)<>'' then
begin
with ADOQuery1 do
begin
Append;
FieldByName('rdate').Value:=Excelid.WorkBooks[1].Worksheets[k].Cells[i,1].Value;
FieldByName('moldid').Value:=Excelid.WorkBooks[1].Worksheets[k].Cells[i,2].Value;
FieldByName('gz').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,3].Value;
FieldByName('amount').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,4].Value;
FieldByName('fkfs').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,5].Value;
FieldByName('maker').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,6].Value;
FieldByName('jgs').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,7].Value;
FieldByName('memo').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,8].Value;
Post;
end;
end
else break;
end; //for
except
adoquery1.Free;
excelid.quit;
showmessage('导入出错!');
end;
finally
excelid.quit;
ADOQuery1.Free;
showmessage('导入成功');
end;
end;end.
1.Exception EOSError in module project1.exe at 0000E3Ae.system error code:1400 无效的窗口句柄.
2.Runtime error 216 at 7C921010以下是我的代码:
unit UMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, Grids, DBGrids, StdCtrls, ExtCtrls,excel2000,OleServer,comObj,
DBGridEh, Unit2;type
TMain = class(TForm)
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
DBGrid1: TDBGridEh;
SaveDialog1: TSaveDialog;
Panel1: TPanel;
Button1: TButton;
OpenDialog1: TOpenDialog;
Button3: TButton;
ADOQuery2: TADOQuery;
Label1: TLabel;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Button2Click(Sender: TObject); private
procedure ThreadDone(Sender:TObject);
{ Private declarations }
public
{ Public declarations }
ExcelToSQL:ImportExcel;
end;var
Main: TMain;implementationuses UDM, Unit1;{$R *.dfm}procedure TMain.Button1Click(Sender: TObject);
var
fname,moldid:string;
excelid:variant;
ColumnCount,sheetcount,i,j,k:integer;
begin
//Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Documents and Settings\Administrator\桌面\6月份外加工费用统计表.xls;Extended Properties=Excel 8.0;Persist Security Info=Falseif (Edit1.Text='') then
begin
MessageDlg('输入的内容为空',mtwarning,[mbOK],0);
exit;
end;
if OpenDialog1.Execute then
fname:=OpenDialog1.FileName
else exit;ExcelToSQL:=ImportExcel.Create(fname);
//ExcelToSQL.Resume;
//ExcelToSQL.OnTerminate:=ThreadDone;
end;procedure TMain.FormCreate(Sender: TObject);
begin
ADOQuery1.Active:=True;
end;procedure TMain.Button3Click(Sender: TObject);
begin
ADOQuery1.Requery();
end;procedure TMain.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9',#8]) then key:=#0;
end;procedure TMain.Button2Click(Sender: TObject);
begin
with TForm1.Create(self) do
Show;
end;procedure TMain.ThreadDone(Sender:TObject);
begin
// showmessage('success');
end;end.unit Unit2;interfaceuses
Classes,ADODB,comobj,excel2000,oleserver,SysUtils;type
ImportExcel = class(TThread)
private
Fullfilename:string;
ADOQuery1:TADOQuery;
k:integer;
procedure GetEditText;
{ Private declarations }
protected
procedure Execute; override;
public
Constructor Create(filename:string);
end;implementationuses UMain,dialogs;{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure ImportExcel.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ ImportExcel }Constructor ImportExcel.Create(filename:string);
begin
Fullfilename:=filename;
Inherited Create(False);
end;procedure ImportExcel.GetEditText;
begin
k:=StrToInt(Main.Edit1.text);
end;procedure ImportExcel.Execute;
var
excelid:variant;
i:integer;
begin
{ Place thread code here }
excelid:=Createoleobject('Excel.Application'); //1、创建连接
excelid.visible:=false;
excelid.workbooks.open(Fullfilename); //2、指定文件
Synchronize(GetEditText);Try
try
ADOQuery1:=TADOQuery.Create(nil);
with ADOQuery1 do
begin
ConnectionString:='Provider=MSDASQL.1;Persist Security Info=True;User ID=wu;Data Source=mjgl';
Close;
SQL.Clear;
SQL.Text:='select * from jgfy';
Open;
end;
for i:=3 to 1000 do //最大行数1000
begin
//判断是否结束
if Trim(Excelid.WorkBooks[1].Worksheets[k].Cells[i,1].Value)<>'' then
begin
with ADOQuery1 do
begin
Append;
FieldByName('rdate').Value:=Excelid.WorkBooks[1].Worksheets[k].Cells[i,1].Value;
FieldByName('moldid').Value:=Excelid.WorkBooks[1].Worksheets[k].Cells[i,2].Value;
FieldByName('gz').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,3].Value;
FieldByName('amount').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,4].Value;
FieldByName('fkfs').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,5].Value;
FieldByName('maker').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,6].Value;
FieldByName('jgs').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,7].Value;
FieldByName('memo').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,8].Value;
Post;
end;
end
else break;
end; //for
except
adoquery1.Free;
excelid.quit;
showmessage('导入出错!');
end;
finally
excelid.quit;
ADOQuery1.Free;
showmessage('导入成功');
end;
end;end.
finally
excelid.quit;
ADOQuery1.Free;
showmessage( "导入成功 ");
我明明退出了EXCEL程序(excelid.quit) 但是在任务管理器中还是有很多EXCEL进程?
这是怎么回事?
那应该怎么关闭线程?请教~~!
我设了FreeOnTerminate:=True
例如:你可以用参数1=0表示成功.参数1=1表示失败.处理消息的函数:
procedure xx(var m:Tmessage); message 消息名;一旦接收到消息,就知道是成功了还是失败了.
就像迅雷一样,可下载多个文件,每个都可以显示其状态(成功还是不成功)!怎么做呢?
是不是要自定义一个消息??~~
unit UMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, Grids, DBGrids, StdCtrls, ExtCtrls,excel2000,OleServer,comObj,
DBGridEh, Unit2;
Const
UM_SUCCESS=WM_USER+100;
type
TMain = class(TForm)
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
DBGrid1: TDBGridEh;
SaveDialog1: TSaveDialog;
Panel1: TPanel;
Button1: TButton;
OpenDialog1: TOpenDialog;
Button3: TButton;
ADOQuery2: TADOQuery;
Label1: TLabel;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Button2Click(Sender: TObject); private
ThreadsRuning:integer;
procedure ThreadDone(Sender:TObject);
procedure UMSuccess(var Msg:TMessage);message UM_SUCCESS;
{ Private declarations }
public
{ Public declarations }
ExcelToSQL:ImportExcel;
end;var
Main: TMain;implementationuses UDM, Unit1;{$R *.dfm}procedure TMain.UMSuccess(var Msg:TMessage);
begin
//add code here.
if Msg.WParam=0 then showmessage('导入成功')
else showmessage('导入失败');
end;
procedure TMain.Button1Click(Sender: TObject);
var
fname,moldid:string;
excelid:variant;
ColumnCount,sheetcount,i,j,k:integer;
begin
//Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Documents and Settings\Administrator\桌面\6月份外加工费用统计表.xls;Extended Properties=Excel 8.0;Persist Security Info=Falseif (Edit1.Text='') then
begin
MessageDlg('输入的内容为空',mtwarning,[mbOK],0);
exit;
end;
if OpenDialog1.Execute then
fname:=OpenDialog1.FileName
else exit;ExcelToSQL:=ImportExcel.Create(fname);
//ExcelToSQL.Resume;
ExcelToSQL.OnTerminate:=ThreadDone;{
try
Screen.Cursor := crHourGlass; //显示漏斗光标
excelid:=Createoleobject('Excel.Application'); //1、创建连接
excelid.visible:=false;
//showmessage(fname);
excelid.workbooks.open(fname); //2、指定文件
adoquery1.Active:=true;
k:=StrToInt(edit1.Text);
//try
//dm.ADOCon.BeginTrans //开始一个事务
for i:=3 to 1000 do //最大行数1000
begin
//判断是否结束
if Trim(Excelid.WorkBooks[1].Worksheets[k].Cells[i,1].Value)<>'' then
begin
with ADOQuery1 do
begin
Append;
FieldByName('rdate').Value:=Excelid.WorkBooks[1].Worksheets[k].Cells[i,1].Value;
FieldByName('moldid').Value:=Excelid.WorkBooks[1].Worksheets[k].Cells[i,2].Value;
FieldByName('gz').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,3].Value;
FieldByName('amount').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,4].Value;
FieldByName('fkfs').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,5].Value;
FieldByName('maker').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,6].Value;
FieldByName('jgs').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,7].Value;
FieldByName('memo').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,8].Value;
Post;
end;
end
else break;
end;
//dm.ADOCon.CommitTrans;
//except
//dm.ADOCon.RollbackTrans; //回滚
//end; Screen.Cursor := crDefault;
MessageDlg('数据导入成功!',mtInformation,[mbOK],0);
excelid.quit;
except
excelid.quit;
showmessage('导入出错!');
end;
}
end;procedure TMain.FormCreate(Sender: TObject);
begin
ADOQuery1.Active:=True;
ThreadsRuning:=0;
end;procedure TMain.Button3Click(Sender: TObject);
begin
ADOQuery1.Requery();
end;procedure TMain.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9',#8]) then key:=#0;
end;procedure TMain.Button2Click(Sender: TObject);
begin
with TForm1.Create(self) do
Show;
end;procedure TMain.ThreadDone(Sender:TObject);
begin
Inc(ThreadsRunning);
if ThreadsRunning=3 then
begin
Button1.Enabled:=False;
showmessage('Max');
end;
end;end.
//线程单元,SendMessage这个函数包含在哪个单元中?
unit Unit2;interfaceuses
Classes,ADODB,comobj,excel2000,oleserver,SysUtils;type
ImportExcel = class(TThread)
private
Fullfilename:string;
// ADOConnect:TADOConnection;
ADOQuery1:TADOQuery;
k:integer;
procedure GetEditText;
{ Private declarations }
protected
procedure Execute; override;
public
Constructor Create(filename:string);
end;implementationuses UMain,dialogs;{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure ImportExcel.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ ImportExcel }Constructor ImportExcel.Create(filename:string);
begin
Fullfilename:=filename;
Inherited Create(False);
end;procedure ImportExcel.GetEditText;
begin
k:=StrToInt(Main.Edit1.text);
end;procedure ImportExcel.Execute;
var
excelid:variant;
i:integer;
begin
{ Place thread code here }
excelid:=Createoleobject('Excel.Application'); //1、创建连接
excelid.visible:=false;
excelid.workbooks.open(Fullfilename); //2、指定文件
Synchronize(GetEditText);
//self.FreeOnTerminate:=True; //使线程结束时,触发OnTerminate事件Try
try
ADOQuery1:=TADOQuery.Create(nil);
with ADOQuery1 do
begin
ConnectionString:='Provider=MSDASQL.1;Persist Security Info=True;User ID=wujy;Data Source=mjgl';
Close;
SQL.Clear;
SQL.Text:='select * from jgfy';
Open;
end;
for i:=3 to 1000 do //最大行数1000
begin
//判断是否结束
if Trim(Excelid.WorkBooks[1].Worksheets[k].Cells[i,1].Value)<>'' then
begin
with ADOQuery1 do
begin
Append;
FieldByName('rdate').Value:=Excelid.WorkBooks[1].Worksheets[k].Cells[i,1].Value;
FieldByName('moldid').Value:=Excelid.WorkBooks[1].Worksheets[k].Cells[i,2].Value;
FieldByName('gz').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,3].Value;
FieldByName('amount').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,4].Value;
FieldByName('fkfs').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,5].Value;
FieldByName('maker').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,6].Value;
FieldByName('jgs').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,7].Value;
FieldByName('memo').Value:= Excelid.WorkBooks[1].Worksheets[k].Cells[i,8].Value;
Post;
end;
end
else break;
end; //for
except
adoquery1.Free;
excelid.quit;
SendMessage(Main.Handle,UM_SUCCESS,1,0);
// showmessage('导入出错!');
end;
finally
excelid.quit;
ADOQuery1.Free;
SendMessage(Main.Handle,UM_SUCCESS,0,0);
// showmessage('导入成功');
end;
end;end.
TOnFinish = procedure(Sender: TObject; ASuccess: Boolean) of object;procedure ImportExcel.DoFinish()
begin
if Assigned(FOnFinish) then
try
FOnFinish(Self, FSuccess);
except
end;
end;这里只是大概说一下,具体实现自己去概括。
begin
if Assigned(FOnFinish) then
try
FOnFinish(Self, FSuccess);
except
end;
end; C++ 程序写多了,Delphi 语法都忘了