请光顾:小问题 (100分)

  • 主题发起人 主题发起人 lsz_615
  • 开始时间 开始时间
L

lsz_615

Unregistered / Unconfirmed
GUEST, unregistred user!
一个TClientDataSet控件
它在执行sql语句时,出现下面错误提示:
“尚未调用CoInitialize”,请问这是什么原因造成的?

我把查询做在一个线程里面,把这个控件当参数传递过去,当它执行sQL语句时,就出现下面的错误![:(]
我的部分代码
unit UQueryWaiting;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
ComCtrls, StdCtrls, Buttons, ExtCtrls, DB, DBClient, activex;

type
TQueryWaiting = class(TThread)
private
FQuery: TClientDataSet;
FQueryException: Exception;
FMemo: TMemo;
procedure ComInitLost;
{ Private declarations }
protected
procedure Execute; override;
public
constructor Create(Q:TClientDataSet; Memo: TMemo); virtual;
end;

type
TFrmQWaiting = class(TForm)
Animate1: TAnimate;
Bevel1: TBevel;
btnok: TBitBtn;
btncancel: TBitBtn;
Label2: TLabel;
Timer1: TTimer;
Memo1: TMemo;
procedure btnokClick(Sender: TObject);
procedure btncancelClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
Information_v,StatBar_v: string;
Qeruy_v : TClientDataSet;
newthread: TQueryWaiting;
startTime: TTime;
{ Private declarations }
public
{ Public declarations }
end;

procedure ShowQueryMessage(ClientDataSet: TClientDataSet);
[yellow]主界面的ClientDataSet就是通过这个函数传递过来的[/yellow]

implementation

{$R *.dfm}

procedure TQueryWaiting.ComInitLost;
var
Msg: string;
begin
Msg := FQueryException.Message;
if (Msg <> '') and (AnsiLastChar(Msg) > '.') then Msg := Msg + '.';
FMemo.Hint:=Msg;
end;

constructor TQueryWaiting.Create(Q: TClientDataSet; Memo: TMemo);
begin
inherited Create(true);
FQuery := Q;
FMemo := Memo;
FreeOnTerminate := True;
resume;
end;

procedure TQueryWaiting.Execute;
begin
//Coinitialize(nil);
try
FQuery.Open;
except
FQueryException := ExceptObject as Exception;
Synchronize(ComInitLost);
end;
//CoUninitialize;
end;
代码:
[blue]这里如果加上coinitialize语句的话,又会出现“应用程序调用一个已为另一线程整理的界面。”这样的错误,查询还是不能继续。
其它的地方加上,则还是报上面的错误![/blue]

procedure ShowQueryMessage(Information,StatBarC: string; ClientDataSet: TClientDataSet);
begin
with TFrmQWaiting.Create(Application) do
begin
Caption:=StatBarC;
StatBar_v:=StatBarC;
Qeruy_v:=ClientDataset;
Information_v:=Information;
Show;
end;
end;

procedure TFrmQWaiting.btnokClick(Sender: TObject);
begin
Timer1.Enabled:=false;
Timer1.OnTimer:=Timer1Timer1;
Label2.Caption:='耗时:00:00:00';
Timer1.Enabled:=true;
Memo1.Lines.Clear;
Animate1.Active:=true;
if Information_v='' then
Memo1.Lines.Add('操作正在进行,请稍候...')
else Memo1.Lines.Add(Information_v);
Memo1.Lines.Add('中止操作,请点击【取消】按钮。');
btnok.Enabled:=false;
newthread:=TQueryWaiting.Create(Qeruy_v,Memo1);
repeat
Application.ProcessMessages;
until Qeruy_v.Tag>0;
Memo1.Lines.Clear;
Timer1.Enabled:=false;
btnok.Visible:=false;
Animate1.Active:=false;
if Qeruy_v.Tag=1 then //sucess
begin
Memo1.Text:=caption+'-操作成功完成';
Caption:='成功完成';
Timer1.OnTimer:=Timer1Timer2;
StartTime:=now;
Timer1.Enabled:=true;
end
else if Qeruy_v.Tag=2 then //lost
begin
Memo1.Lines.Add(caption+'-操作失败,原因:');
Memo1.Lines.Add(memo1.Hint);
Caption:='操作失败';
end;
end;

procedure TFrmQWaiting.btncancelClick(Sender: TObject);
begin
if newthread<>nil then
try
newthread.Terminate;
except
end;
Close;
end;
 
以前人家好像说过这个问题,记得是在创建ClientDataSet的单元里面写上CoInitialize
 
在主窗体单元中申明:
function CoInitialize(pvReserved: Pointer):HResult;
external 'ole32.dll' name 'CoInitialize';
procedure CoUninitialize; external 'ole32.dll';

在线程单元中引用主窗体单元
procedure MyThread.Execute;
var
hr : HResult;
begin
{ Place thread code here }
hr := CoInitialize(nil);
//你的处理语句
CoUninitialize;
end;
 
又是borland的一个bug而已,

在dll中调用ado组件也会出现同样的问题。
 
help me!
怎么没有人回答这个问题?
我已经把以前的问题都看过了,但都不好使!
有没有对这个问题有深入了解的?
真真是急死人!
 
不满意!
 
后退
顶部