起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 515|回复: 10

【结】olecontainer打开word问题

[复制链接]
发表于 2010-1-25 10:38:13 | 显示全部楼层 |阅读模式
我用olecontainer打开word报错,如图。这是怎么回事呢?

qq截图未命名11.jpg

11.69 KB, 下载次数: 242

回复

使用道具 举报

发表于 2010-1-25 11:26:35 | 显示全部楼层
是新做的功能?
还是原先好的,现在才出错?
还是有些机器好的,有些机器不行?
如果是新做功能,是否用到第三方的东东?我用这个错误信息搜索了一下,有两个帖子你参考一下,

如果没有第三方的,那么把代码贴出来看看。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-1-25 11:33:43 | 显示全部楼层
没有第三方控件,就是用X3自带的olecontainer。
两段关键代码
procedure TCT_BZGFH_BZXXWH.SaveToField(AField:TDataField;AOle:TOleContainer);
var
  lStream: TMemoryStream;
begin
  lStream := TMemoryStream.Create;
  try
    AOle.AllowInPlace := True;
    AOle.SaveToStream(lStream);
    //AOle.SaveToFile('c:\savetmp.doc');
    if  not AField.DataSet.Active then AField.DataSet.Open;
    AField.DataSet.Edit;
    TBlobField(AField).LoadFromStream(lStream);
    //TBlobField(AField).LoadFromFile('c:\savetmp.doc');
    AField.DataSet.Post;
  finally
    lStream.Free;
  end;
end;
把ole的流存入数据库
procedure TCT_BZGFH_BZXXWH.ReadFromField(AField:TDataField;AOle:TOleContainer);
var
  lStream: TMemoryStream;
begin
  lStream := TMemoryStream.Create;
  AOle.DestroyObject;
  try
    AOle.AllowInPlace := True;
    if  not AField.DataSet.Active then AField.DataSet.Open;
    //AField.DataSet.Edit;
    //lStream := TMemoryStream(AField.DataSet.CreateBlobStream(AField,TBlobStreamMode.bmRead));
    TBlobField(AField).SaveToFile('c:\loadtmp.doc');
    //TBlobField(AField).SaveToStream(lStream);
    //AOle.CleanupInstance;
    lStream.Position := 0;
    //AOle.CreateObjectFromFile('c:\loadtmp.doc',false);
    AOle.LoadFromFile('c:\loadtmp.doc');
    AOle.DoVerb(ovShow);
    //AOle.LoadFromStream(lStream);
  finally
    lStream.Free;
  end;
end;
读来自数据库的流

我是想在界面上显示客户上传的word文件。我在pagecontrol放了两个olecontainer,用户上传不同的word文件,存入数据库,显示的时候,就显示olecontainer里面。现在出现的问题是,如果数据库里有内容,显示的时候就会报1楼的错误。如果是上传文件的话,这两个olecontainer就显示正常。非常奇怪的问题,我总不能每次都让用户上传一下word文件吧。

另,上传的代码与olecontainer有关的:
lOle.CreateObjectFromFile(OpenDialog1.FileName,False);
        lOle.DoVerb(ovShow);
回复 支持 反对

使用道具 举报

发表于 2010-1-25 16:14:42 | 显示全部楼层
楼主,看你描述,是从数据库中读取出来的word显示就出问题,是吗?我对你的话没有太了解

如果是,ReadFromField 这个过程是想把存入数据表的字段的word内容显示到olecontainer上?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-1-26 10:10:51 | 显示全部楼层
回复 支持 反对

使用道具 举报

发表于 2010-1-26 10:39:23 | 显示全部楼层
http://bbs.justep.com/forum.php?mod=viewthread&tid=18861
好像没有好的方法。
只能存成本地文件在打开了。
TBLobField(DataSetBroker1.dataSet.FieldByName('word')).LoadFromFile('c:\b.doc');   //存到数据库  
TBLobField(DataSetBroker1.dataSet.FieldByName('word')).SaveToFile('c:\b.doc');     //存到本地
     OleContainer1.CreateObjectFromFile('c:\b.doc',false);  //打开本地文件
    OleContainer1.DoVerb(1);
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-1-26 16:55:16 | 显示全部楼层
我找到了一个解决方法。因为发现用CreateObjectFromFile以后窗口都正常,所以猜测在载入数据之前是否要先创建一个什么对象,所以读取代码改成如下:
procedure TCT_BZGFH_BZXXWH.ReadFromField(AField:TDataField;AOle:TOleContainer);
var
  lStream: TMemoryStream;
begin
  lStream := TMemoryStream.Create;
  AOle.DestroyObject;
  AOle.CreateObject('Word.Application',false);
  try
    AOle.AllowInPlace := True;
    if  not AField.DataSet.Active then AField.DataSet.Open;
    //AField.DataSet.Edit;
    //lStream := TMemoryStream(AField.DataSet.CreateBlobStream(AField,TBlobStreamMode.bmRead));
    //TBlobField(AField).SaveToFile('c:\loadtmp.doc');
    TBlobField(AField).SaveToStream(lStream);
    //AOle.CleanupInstance;
    lStream.Position := 0;
    //AOle.CreateObjectFromFile('c:\loadtmp.doc',false);
    //AOle.LoadFromFile('c:\loadtmp.doc');
    AOle.LoadFromStream(lStream);
    AOle.DoVerb(ovShow);
  finally
    lStream.Free;
  end;
end;

结果顺利能显示。折腾了好久了,给大家分享一下。
另回楼上,楼上的方法我已经试过,用CreateObjectFromFile的方法从数据库读取是不行的,也报错。还有一个问题,打开后的word怎么关闭,不然的话每读一次都会在后台打开一个word,只开不关的话,这样下去。。。
回复 支持 反对

使用道具 举报

发表于 2010-1-27 09:21:56 | 显示全部楼层
AOle.DestroyObject;
  AOle.CreateObject('Word.Application',false);
把这两句去掉不行么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-1-27 21:19:40 | 显示全部楼层
AOle.DestroyObject;也许可以去掉,不过未实验。AOle.CreateObject('Word.Application',false);是不可以去掉的。
回复 支持 反对

使用道具 举报

发表于 2010-1-28 09:11:17 | 显示全部楼层
procedure TMainForm.Button5Click(Sender: TObject);
var lStream :TMemoryStream;
begin
  lStream :=TMemoryStream.Create;
   //OleContainer1.SaveToStream(lStream);
  try
  OleContainer1.CreateObjectFromFile('c:\a.doc',false);
  OleContainer1.SaveToStream(lStream);
  lStream.Position := 0;
  //TBLobField(DataSetBroker1.DataSet.FieldByName('word')).LoadFromStream(lStream);
  DataSetBroker1.DataSet.Edit;
  TBLobField(DataSetBroker1.DataSet.FieldByName('word')).LoadFromStream(lStream);
  DataSetBroker1.DataSet.ApplyUpdates;
  finally
   lstream.Free;
  end;

  //TBLobField(DataSetBroker1.dataSet.FieldByName('word')).SaveToFile('c:\c.doc');
end;

procedure TMainForm.Button4Click(Sender: TObject);
var lStream :TMemoryStream;
begin
  lStream :=TMemoryStream.Create;
  try
  TBLobField(DataSetBroker1.DataSet.FieldByName('word')).SaveToStream(lStream);
  lStream.Position := 0;
  OleContainer1.LoadFromStream(lStream);
  OleContainer1.DoVerb(1);
  finally
  lStream.Free;
  end;
end;

上面是我的测试代码,我这里是可以在OleContainer1中打开word的。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-7-12 06:29 , Processed in 0.044661 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表