CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

请教如何编写编写这样的控件,使之能在Word中“插入”->“对象”中出现并使用它

楼主huojiehai(海天子)2006-01-07 13:01:04 在 Delphi / VCL组件开发及应用 提问

如题.  
          希望有这方面的资料介绍一下!! 问题点数:200、回复次数:13Top

1 楼zhlwyy(生活很累,但是因为生活才有意义。)回复于 2006-01-07 13:05:16 得分 10

海天的帖子是要顶的  
  关注一下  
  你的身体好些了吧^_^Top

2 楼yq3woaini(哈哈镜 选择好心情)回复于 2006-01-07 14:05:43 得分 0

关注,我试一下Top

3 楼yq3woaini(哈哈镜 选择好心情)回复于 2006-01-07 14:13:29 得分 0

用Delphi封装好ActiveX控件  
  regsvr32注册一下,就可以了,找到添加了  
  Top

4 楼huojiehai(海天子)回复于 2006-01-07 14:21:33 得分 0

谢   谢   zhlwyy   ,  
    身体还可以  
   
  yq3woaini   在   哪添   加  
   
  Top

5 楼huojiehai(海天子)回复于 2006-01-07 14:28:23 得分 0

yq3woaini,   具体说一下:应该编写为哪类型的ActiveX,然后该怎么注册  
   
  另外加进你的名字中文部分在发出回复时会提示“请不要发表可能给我们带来伤害的言论,谢谢配合”可能是星星导致的  
  哈哈镜(中级代码工)Top

6 楼aiirii(ari-http://spaces.msn.com/members/aiirii/)回复于 2006-01-07 16:01:15 得分 50

如没有记错的话,应该是用   OLE   Automation   就可Top

7 楼aiirii(ari-http://spaces.msn.com/members/aiirii/)回复于 2006-01-07 16:03:19 得分 0

http://news.softhouse.com.cn/news/show/13684.htmlTop

8 楼yq3woaini(哈哈镜 选择好心情)回复于 2006-01-07 17:18:16 得分 130

摘自大富翁ycguser  
   
  刚开发开发此控件时,首先是想到此控件的数据要序列化到WORD文档中。  
  在建立工程时,我采用了ActiveXForm.   我在ActivexForm中加入一个USERNAME(String型)的属性后,将控件放到WORD中,发现USERNAME无法序列化到WORD文档中。这时我发现比较难办。如果这个基本的功能实现不了,那个这个控件根本无法开发下去。于是我查看了基类:TActiveXControl   ,发现它已经实现了好几个序列化的接口。经过一天的调试跟踪,也没有搞明白它序列化方面的原理。现实的结果是在WORD中存不住数据。根据C++经验,只有自己去实现序列化的接口,但经过对系统支持的几个序列化接口试验以后,才发现只有实现IPersistStorage接口在WORD中才能序列化数据。  
  下面是是IPersistStorage实现的代码:  
  TCanvasForm   =   class(TActiveForm,   ICanvasForm,IPersistStorage)  
      private  
          {   Private   declarations   }  
          FUserName:String;     //用户名称  
          FDataTime:string;     //取得笔迹数据的时间  
          FWriteTime:Integer;   //返回的时间  
          FIndata:oleVariant;         //笔迹数据变量   array   of   byte   的变量  
          FisScale:boolean;   //记录图片是否比image大  
          FLastTime:Integer;  
          bdirty:Boolean;   //是否保存标识  
    public  
            ///////IPersistStorage  
          function   IsDirty:   HResult;   stdcall;  
          function   InitNew(const   stg:   IStorage):   HResult;   stdcall;  
          function   Load(const   stg:   IStorage):   HResult;   stdcall;  
          function   Save(const   stgSave:   IStorage;   fSameAsLoad:   BOOL):   HResult;  
              stdcall;  
          function   SaveCompleted(const   stgNew:   IStorage):   HResult;   stdcall;  
          function   HandsOffStorage:   HResult;   stdcall;  
          function   GetClassID(out   classID:   TCLSID):   HResult;   stdcall;  
  end;  
  ////////////////////IPersistStoge  
          function   TCanvasForm.IsDirty:   HResult;   stdcall;  
          begin  
            //if   bdirty   then  
            //   Result   :=   S_False  
            //else  
              result:=S_OK;  
          end;  
          function   TCanvasForm.InitNew(const   stg:   IStorage):   HResult;   stdcall;  
          begin  
            Result   :=   S_OK;  
          end;  
          function   TCanvasForm.Load(const   stg:   IStorage):   HResult;   stdcall;  
          var  
            stmData:IStream;  
            OS:TOleStream;  
            read:TReader;  
            elementcount:integer;  
            bty:array   of   byte;  
          begin  
            if   SUCCEEDED(stg.OpenStream('PropData',nil,   STGM_READWRITE   or   STGM_SHARE_EXCLUSIVE,0,stmData))   then  
            begin  
              OS:=TOleStream.Create(stmData);  
              try  
                    read:=Treader.Create(oS,4096);  
                  try  
                    FUserName:=read.ReadWideString;  
                    FDataTime:=read.ReadWideString   ;  
                    self.Height   :=trunc(read.ReadSingle)   ;  
                    self.Width   :=trunc(read.ReadSingle)   ;  
                    self.FLastTime:=trunc(read.ReadSingle   );  
                    elementcount:=trunc(read.ReadSingle   );  
                finally  
                      read.Free;  
                  end;  
              finally  
                OS.Free;  
              end;  
            end;  
            Result   :=   S_OK;  
          end;  
           
          function   TCanvasForm.Save(const   stgSave:   IStorage;   fSameAsLoad:   BOOL):   HResult;  
              stdcall;  
          var  
            stmData:IStream;  
            OS:TOleStream;  
            write:TWriter;  
            arrayElement:integer;  
            p:pointer;  
          begin  
            //   if   not   SUCCEEDED(stgSave.OpenStream('ss',nil,   STGM_READWRITE   or   STGM_SHARE_EXCLUSIVE,0,stmData))   then  
              OleCheck(stgSave.CreateStream('PropData',STGM_CREATE   or   STGM_READWRITE   or   STGM_SHARE_EXCLUSIVE,0,0,stmData));  
                OS:=TOleStream.Create(stmData);  
                try  
                  write:=TWriter.Create(OS,4096);  
                    try  
                      write.WriteWideString(FUserName);  
                      write.WriteWideString(FDataTime);  
                      write.WriteSingle(Height);  
                      Write.WriteSingle(Width);  
                      write.WriteSingle(FLastTime);    
                      /////////////   开始写变体数据  
                      if   not   VarIsEmpty(self.FIndata)   then  
                      begin  
                            arrayElement:=VarArrayHighBound(Findata,1)+1;  
                            write.WriteSingle(arrayElement);  
                            p   :=   VarArrayLock(Findata);  
                            try  
                                  write.Write(p^,   arrayElement);  
                            finally  
                                  VarArrayUnlock(Findata);  
                            end;  
                      end  
                      else  
                      begin  
                            arrayElement:=-1;  
                            write.WriteSingle(arrayElement);  
                      end;  
                  finally  
                      write.Free;  
                  end;  
              finally  
                  OS.Free;  
              end;  
            bdirty:=true;  
            Result   :=   S_OK;  
          end;  
          function   TCanvasForm.SaveCompleted(const   stgNew:   IStorage):   HResult;   stdcall;  
          begin  
            Result   :=   S_OK;  
          end;  
          function   TCanvasForm.HandsOffStorage:   HResult;   stdcall;  
          begin  
            Result   :=   S_OK;  
          end;  
          function   TCanvasForm.GetClassID(out   classID:   TCLSID):   HResult;   stdcall;  
          begin  
              classID:=Class_CanvasForm;  
              Result   :=   S_OK;  
          end;    
   
  Top

9 楼yq3woaini(哈哈镜 选择好心情)回复于 2006-01-07 17:20:20 得分 0

Activex   Automation   objectTop

10 楼yq3woaini(哈哈镜 选择好心情)回复于 2006-01-07 17:22:59 得分 0

分类:ActiveX   控件   (   版主:satanmonkey,   zyy04   )      
  来自:wxss,   时间:2005-9-28   14:41:00,   ID:3221853   [显示:小字体   |   大字体]      
   
  各位大哥:  
          我在大富翁和K.top上,一直想和各位高手请教一些关于用delphi   实现ActiveX   Document   Server的问题。问题的提出是源于这样一个需求。我做了一个类似图形编辑的软体,用自己的程序生成自己定义的文件格式。但用户提出,需要将编辑好的东西嵌入到word文档里。我见到类似的软件实现了这个功能(如公式编辑器):它们在word里注册了一个可插入的对象,当我们新插入一个自己的对象,双击这个对象的时候,就可以回到我自己的软体里来编辑这个对象。编辑完成,退出程序,word里的对象也更新了。  
          我在网上找了很久,也请教了很多高手,但似乎用delphi难以实现这样的功能。甚至连如何注册成一个可插入的对象都让我难以下手。后来我发现borland新闻组里有人介绍一篇1999年的文章介绍过这类的实现,还有源码http://www.thedelphimagazine.com/disks/dmag43.zip,http://www.thedelphimagazine.com/disks/dmag42.zip,   在comcorn目录里)。该程序建立了一个Tmemo类型的可插入对象,并成功地实现了注册成一个可插入的对象。我把Tmemo类型换成其他类型如TButton,Tpanel都可以,   但有几个问题似乎是还没有解决:  
   
  1.双击word里的这个对象,不能回到自己的软体进行编辑。更谈不上如何将编辑后的结果再更新到word里了。(老外的这个程式里提供了一些思路,即重载SaveToStream(const   Stream:   IStream);和LoadFromStream(const   Stream:   IStream);来传递对象的信息,但似乎没起作用),各位老大,这些地方该如何改进呢?  
   
  2。老外的程序的这个TActiveXDocument对象是从TActiveXControl继承来的,在word里点击它似乎无法获得焦点,反复几次后就出错了。是不是选择从TActiveXControl继承本身就是错的?应该从哪个对象继承呢?TActiveFormControl?  
   
  3。我所见过的可以实现上述需求的软体(如公式编辑器)是这样操作的,在word里单击对象,则选中,双击对象则调出程式主界面,开始编辑,存盘后退出,更新word里的对象显示。这个在程序里,我想是要重载DOverb方法来实现吧,但我一直没有成功。:(,怎么样能找到并响应这个双击事件呢?  
   
   
   
  也许,关注这个问题的朋友会在http://www.evocorp.com/Delphi/ADDActiveDocuments.htm里找到另外的线索,我比较了它和comcorn的区别,很明显的是,他们之间有很类似的地方(作者在2004年才做的更新),而且,它没有demo,根据它提示的方法,我花了9牛2虎的力气建立了一个sample,但效果和dmag42.zip,comcorn有同样的问题。  
   
  我自己写的demo,基本上是沿袭了dmag42.zip的框架(想要的大哥说一声,email给您),注意,不要用它给的AxCtrls.pas(delphi自己有),在uses里要加入Variants,omgw.[1]   :=   1;改成omgw.width[1]   :=   1;就可以编译成功了。运行一次程序,在word里,你就会发现,在插入--对象里有一项“delphi   activex   Document   object”了。  
   
   
  这个问题很有挑战性,我研究了很久,但始终不得要领,希望各位大哥齐心协力,能在此基础上有所突破,让小弟寝食能安。  
  这真是一个难于归类的问题,但希望其他版的版主也能关注,尝试一下如何解决这个问题,小弟不甚感激。        
  Top

11 楼maming2003(關機.睡覺!)回复于 2006-01-07 21:45:48 得分 5

楼上的正解Top

12 楼clasj(★知我☆)回复于 2006-01-08 14:07:27 得分 5

太强了,好多星星啊,帮顶!Top

13 楼huojiehai(海天子)回复于 2006-01-08 14:57:46 得分 0

如果单是Activex   Automation   object,delphi的Demo就有例子,但好像没这么简单Top

相关问题

  • 如何编写word控件?
  • 怎样用VB.NET编写可插入到网页中的控件?
  • 关于控件插入word问题
  • 在word中插入ocx控件的问题
  • 如何用VC在word里插入用MFC写的控件
  • 如果将插入WORD的ActiveX控件对象持久化到WORD文档中?
  • 关于插入OLE控件时,在插入Microsoft Word文档和Microsoft Word图片时,错误的问题
  • 怎样编写DBGrid控件?
  • 编写自定义控件
  • 编写控件的问题!

关键词

  • word
  • 控件
  • 序列化
  • 接口
  • 数据
  • 文档
  • 注册
  • delphi
  • zip
  • 对象

得分解答快速导航

  • 帖主:huojiehai
  • zhlwyy
  • aiirii
  • yq3woaini
  • maming2003
  • clasj

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo