你的客户端程序必须实现ActiveX文档服务.也就是说必须支持ActiveX Document实现4个接口:
IOleDocumentSite
IOleClientSite
IOleInPlaceSite
IOleInPlaceFrame
IOleDocumentSite
IOleClientSite
IOleInPlaceSite
IOleInPlaceFrame
解决方案 »
- 请教两个JavaScript实现下拉框图片显示和Input可自动调整大小的问题
- JQuery怎么向上滚动一页,我的只能向上滚动一行
- 在网上直接复制html网页到本地打开不正常,请帮忙看看
- js相关问题
- 一个页面要根据 url进行显示广告 该怎么写 谢谢
- 急●●●请教高手如何把此代码应用到PHP中???
- 两个js方法体一样,传的参数不同的问题
- 怎么用javascript让div的滚动条的位置处于最下方?
- javascript怎么判断窗口宽度
- 我写了一个JAVASCRIPT的闹铃程序不知那里错了,请提个醒?
- 我用window.showModalDialog模式时,如果再次调用就它就重新打开一个网页,我想不用重新打开有什么办法
- ie版本6.0.2800.1106.xpclient.010817-1148,获得iframe中对象的问题
而成的,它是一种可以从Web服务器下载的特殊文档类型,当浏览器发
现ActiveX文档文件时,它自动从硬盘上装入对应的ActiveX文档服务
程序,并且服务程序接管了整个浏览器窗口,用以显示文档的内容,用
户可以查看文档的内容,也可以编辑文档,但不能上载回服务器。例如
,我们在In ternet Explorer 3.0或更高版本的浏览器中访问Web服务
器上的Excel文件(.xls)时,只要本地硬盘上安装了Microsoft Excel
电子表格软件,浏览器就会利用Excel打开.xls文件,并且Excel软件界
面和浏览器界面结合在一起。对用户来说,除了启动程序时有一点延
时之外,感觉不到有两个独立的程序在运行,而且,浏览器中的历史记
录也会把该文档作为W eb页面记录下来,以后"后退"时仍然可以回到
该页面。
图1 ActiveX文档示例图和(a)ActiveX文档
本文试着从技术的角度对ActiveX文档作一介绍。
一、ActiveX文档特性
ActiveX文档(如图1)是在OLE文档的基础上发展起来的,因此,有
必要对OLE文档(包括嵌入和链接两种情况)和ActiveX文档作一比较。
OLE文档的服务程序在OLE包容器程序的子窗口中运行,并占有包
容器文档视图的一个矩形区域,当文档对象被激活时,服务程序接管了
包容器程序的菜单和工具条;而ActiveX 文档服务程序则接管了包容
器应用的整个框架窗口,并且文档总是处于活动状态。运行在包容器
框架窗口中的ActiveX文档服务程序,其运行方式与它单独运行的模式
基本一样。我们可以从图2看出这种区别显示。
图2 ActiveX文档和OLE文档界面对照
除了在界面特性上ActiveX文档与OLE文档有很大相似之外,Activ
eX文档突破了OLE文档的桌面环境,进一步可以与浏览器(即Microsoft
Internet Explorer)结合起来,如图1 所示,在IE中可以直接打开远
程Web站点上的文档文件,我们只需给出一个URL,比如:http
//www.someone.com/example.doc,于是浏览器会在其窗口中打开
Microsoft Word文档,而且Word会接管浏览器的菜单和工具条。当然,
前提条件是机器上已经安装了Micros oft Word程序,如果没有安装的
话,浏览器会提示下载文档文件。
ActiveX文档服务程序不允许把修改过的结果存回到Internet机
器上,但可以保存在本地硬盘上。也就是说,菜单"File Save"被禁止,
而"File Save As"则可以执行。
ActiveX文档和ActiveX控制都是OLE技术与Internet结合之后发
展起来的新技术,它们都是ActiveX技术体系中的重要组成部分,而且,
Microsoft Internet Explorer是它们共同的包容器,但在行为特性上
两种技术有显著的区别,概括如下:
程序类型不同 ActiveX文档的服务程序运行在自己的进程中,通
常服务程序是一个E XE程序;而ActiveX控制通常是一个DLL或OCX程序
,它运行在其包容器进程中。
界面方式不同 ActiveX文档服务程序占用浏览器的整个窗口;而A
ctiveX控制通常只占用浏览器窗口的一个矩形区域。
在HTML文件中的使用方式不同 ActiveX文档与HTML文件无关,但
可以在HTML中通过超链接指向ActiveX文档文件;而ActiveX控制作为
对象被嵌入在HTML文件中。
数据保存方式不同 ActiveX文档服务程序可以操作磁盘文件,而A
ctiveX控制一般不操作磁盘文件。
服务程序转载方式不同 ActiveX控制可以自动下载并由浏览器登
记注册,而ActiveX 文档服务程序不支持这种特性。
ActiveX文档超越了OLE文档的桌面环境,为浏览器提供了强大的
扩展功能,但由于在浏览器中打开ActiveX文档要求事先在客户机上装
有ActiveX文档服务程序,所以它的使用受到了很大的限制,不过,在一
般的企业内部网(Intranet)环境下,使用ActiveX文档技术,通过浏览
器查看企业内部的一些资料,比起制作复杂的网页或开发专门的查询
系统要方便、快捷得多。
二、ActiveX文档结构模型
ActiveX文档服务程序提供了文档的核心处理功能,包括文档的读
写、文档的显示以及文档的编辑等,包容器程序负责创建并控制Activ
eX文档对象,并把Web服务器上的数据通过适当的接口传递给ActiveX
文档服务程序。由于ActiveX文档技术源于OLE文档,所以ActiveX文档
服务程序与包容器程序之间的接口继承了OLE文档技术中采用的很多
接口:A ctiveX文档服务程序继承了OLE文档服务程序的一些接口,包
括IOleObject、IDataObjec t、IOleInPlaceObject和IOleInPlaceAc
tiveObject;ActiveX文档包容器则继承了OLE文档包容器的一些接口,
包括IOleClientSite和IOleInPlaceSite,并且,ActiveX文档的菜单协
作过程与OLE文档的过程基本一致。
在OLE文档结构的基础上,ActiveX文档服务程序和包容器还实现
了另外一些接口,Ac tiveX文档服务程序实现了IOleDocument、IOleD
ocumentView、IOleCommandTarget和IP rint接口;而ActiveX文档包
容器则实现了IOleDocumentSite接口。
OLE文档服务程序中最关键的函数是IOleObject::DoVerb,当用户
双击嵌入对象或通过菜单激活嵌入对象时,包容器就会调用该函数。
然而,对于ActiveX文档服务程序,最重要的函数是IOleDocumentView:
:UIActivate。UIActivate找到包容器的站点(site)和框架窗口,把框
架窗口设置为服务程序的父窗口,而且使服务程序的窗口覆盖包容器
的框架窗口,然后激活服务程序窗口。
在文档的数据处理方面,ActiveX文档与OLE链接对象的处理类似,
浏览器把文档文件从Web服务器下载到本地的临时目录中,然后调用对
象的IPersistFile::Load函数装载到ActiveX文档服务程序中。
图3显示了ActiveX文档和包容器的接口示意。
图3 ActiveX文档服务程序和包容器程序的接口示意
ActiveX文档技术(二) 三、ActiveX文档服务程序的实现
我们了解了ActiveX文档服务程序的接口后,就可以实现我们自己
的ActiveX文档服务程序了,但如果直接利用Win32 API来编写代码的
话,则完成基本框架的代码量就很大,而且有些基本的接口代码需要CO
M(组件对象模型)原理作为背景知识才能正确编写。Micro soft Visu
al C++ 5.0包含的MFC库(4.2版)提供了完全的框架支持,而且其集成
环境Visu al Studio所提供的AppWizard可快速生成ActiveX文档服务
程序的框架代码,从而大大简化基本代码的编写工作。
在介绍MFC实现ActiveX文档服务程序的机制之前,我们先看一下M
FC库中实现OLE文档服务程序的机制。类似于一般的MDI/SDI程序,支
持OLE文档的OLE Server程序仍然遵循文档/视图(Doc/View)框架结构
,相关的类包括应用类(CWinApp派生类)、CMainFrame(CMDI FrameWnd
派生类)、CChildFrame(CMDIChildWnd派生类)、COleServerDoc派生
类(COleSe rverDoc为CDocument的派生类)、CView的派生类,与一般
应用相比较,支持OLE文档服务特性需要多个类协同工作。
1. 在CWinApp的派生类即应用类中,为支持OLE进行初始化,在Ini
tInstance成员函数中调用AfxOleInit(),对OLE系统DLL进行初始化。
2. CMainFrame不参与OLE过程,所以不必进行变动;但程序在OLE
方式运行时,所使用的框架为CInPlaceFrame(从COleIPFrameWnd派生)
,它负责进行菜单及工具条的处理。
3. CView派生类以及CChildFrame不受OLE的影响,所以不必变动
。
4. Doc类是这些类中变化最大、也是最重要的类,其基类COleSer
verDoc从CDocument 派生,在COleServerDoc中实现了OLE文档所必须
的一些接口:IOleObject、IDataObject、IOleInPlaceObject、IOleI
nPlaceActiveObject和IPersistStorage等。
5. 为了支持OLE文档特性,AppWizard还生成了另一个从COleServ
erItem派生的类,实际上,它代表了真正的OLE对象,它也实现了IOleOb
ject、IDataObject接口。而且,COleS erverItem与COleServerDoc有
很紧密的联系,通过COleServerItem::GetDocument可以获取相应的CO
leServerDoc对象;通过COleServerDoc::GetEmbeddedItem可以获取相
应的CO leServerItem对象。因为COleServerItem对象代表的是OLE文
档对象,所以我们可以把读写数据处理以及对象自身的操作放在COleS
erverItem的虚成员函数中完成,而把通用的文档操作以及对象的编辑
操作放在COleServerDoc以及View类中完成。
MFC对ActiveX文档的支持绝大部分继承于对OLE文档的支持,只是
针对ActiveX文档的新特性重载和添加了一些方法,基本的结构不变。
下面列出相应的改进。
的文档类也从COleSe rverDoc派生。
2. ActiveX文档对象在包容器程序中运行时,它所使用的框架类C
InPlaceFrame从COl eDocIPFrameWnd派生,而COleDocIPFrameWnd类也
是COleIPFrameWnd的派生类。在COleDo cIPFrameWnd中根据ActiveX
文档对象的界面特性,重载了框架改变大小操作的特性(对象服务程序
的窗口完全覆盖了包容器的框架窗口),并把它自己的菜单资源连到框
架上。
3. 代表文档对象的基类为CDocObjectServerItem,它从COleServ
erItem派生。CDocO bjectServerItem类重载了一些操作特性,最主要
的是激活操作(通过OnShow或OnOpen方法实现)。
4. CDocObjectServer类不用于OLE文档服务程序,它实现了新的A
ctiveX文档接口。服务程序创建一个CDocObjectServer类的对象,并
把它与COleServerDoc对象连接起来,我们可以在派生文档类的COleSe
rverDoc::GetDocObjectServer函数中看到其构造代码。然后,文档对
象和与其相连的CDocObjectServer对象协同工作,共同完成ActiveX文
档的功能。CDocObjectServer类实现了IOleDocument和IOleDocument
View接口。通常我们不必从CD ocObjectServer派生新的类。
图4给出了这些类协同工作的结构图。
图4 MFC库实现ActiveX文档
服务程序的类结构图
四、ActiveX文档服务程序示例
以上我们介绍了ActiveX文档的特性、其服务程序和包容器程序
之间的模型关系,并进一步介绍了MFC对ActiveX文档的支持,现在我们
利用Visual C++ 5.0或6.0提供的支持实现一个ActiveX文档服务例程
序。
如果我们从头开始创建工程,则我们可以在AppWizard生成工程的
Step 3对话框中,选中Active Document Server选项,并在Step 4的Ad
vanced Options指定相应的文档文件后缀名,如图5所示。完成了AppW
izard的所有步骤后,我们就得到了一个ActiveX文档服务程序的框架,
但没有任何实际的功能,工程中包含了上一节所介绍的各个类,我们就
可以根据实际的需要,编写代码以实现所需的功能。限于篇幅,这里不
再一一介绍。图5 AppWizard提供ActiveX文档特性支持
另外一种情况是,如果我们已经写好了一个MFC程序,但它不支持A
ctiveX文档特性,为了更好地与Internet以及浏览器协同工作,我们需
要将其升级为ActiveX文档服务程序,这时我们可以选择两种方法:第
一种方法,生成一个空的ActiveX文档框架工程,然后把原先工程中的
代码移到新的框架工程中;第二种方法,对原来的工程进行改造,使其
具有Activ eX文档特性。下面我们用一个例子来说明使用第二种方法
的改造过程。
本文采用的例子是Visual C++自带的例子Scribble(在Visual C+
+光盘的Samples\M FC\Tutorial\Scribble\Step8目录下),其运行如
图6所示。因为例子程序本身已经支持O LE文档,所以我们只要针对Ac
tiveX文档对OLE文档所作的改进对原工程进行修改即可。( 未完待续
)
图6 Visual C++所带例程序Scribble的运行界面ActiveX文档技术(三) 以下是我们所作的改造步骤:
1. 在Visual Studio中打开Scribble工程,首先在预编译头文件S
tdafx.h中添加Acti veX文档支持所需要的头文件:
#include
2. 打开文件Scribitm.h和Scribitm.cpp,把CScribbleItem类的
基类换为CDocObject ServerItem,对这两文件进行全程替换,把COleS
erverItem换为CDocObjectServerItem即可。
3. 打开文件IpFrame.h和IpFrame.cpp,把CInPlaceFrame类的基
类换为COleDocIPFra meWnd,对这两文件进行全程替换,把COleIPFram
eWnd换为COleDocIPFrameWnd即可。
4. 打开文件Scribble.cpp,在BOOL CScribbleApp::InitInstanc
e()函数中,把下面两行:
EnableShellOpen();
RegisterShellFileTypes(TRUE);
插入在以下语句:
m_pMainWnd- DragAcceptFiles();
之后,并且把下面语句:
m_server.UpdateRegistry(OAT_INPLACE_SERVER);
改为:
m_server.UpdateRegistry(OAT_DOC_OBJECT_SERVER);
5. 在ScribDoc.h文件的CScribbleDoc类中加入以下成员函数:
protected:
virtual CDocObjectServer* GetDocObjectServer
(LPOLEDOCUMENTSITE pDocSite)
{ return new CDocObjectServer(this, pDocSite); }
经过上述步骤改造之后,重新编译连接得到的程序支持ActiveX文
档特性,我们可以运行Scribble.exe程序,保存一个SCB文件(Scribb1.
scb文件),并退出Scribble.exe程序(为了使浏览器能识别SCB文件,必
须先单独运行一次,以便注册必要的信息);然后在Interne t Explore
r中打开Scribb1.scb,则可以得到图1所示的结果。如果把Scribble1.
scb放到Web服务器上,则可以通过HTTP协议在浏览器中打开远程的SCB
文件。图1 运行在浏览器中的Scribble程序
五、ActiveX文档包容器程序的实现
我们再来看看ActiveX文档包容器(客户)程序的实现过程。Activ
eX文档包容器程序必须实现4个接口:IOleDocumentSite、IOleClient
Site、IOleInPlaceSite和IOleInPla ceFrame,其用途分别如下:
1. IOleDocumentSite,它是ActiveX文档包容器专用的接口,可使
ActiveX文档对象直接
被包容器程序激活,而不必按照通常的实地(In-Place)激活对象
的方式被激活。Act iveX文档对象调用IOleDocumentSite::ActiveMe
成员函数激活自身,而不再调用IOleObj ect:
:DoVerb函数。
2. IOleClientSite,这是OLE复合文档技术使用的接口,也用于Ac
tiveX文档技术。Ac tiveX文档包容器程序实现该接口,ActiveX文档
对象通过该接口获取它的显示状态、显示区域的大小以及包容器提供
的其他一些资源信息。
3. IOleInPlaceSite,这是OLE复合文档技术使用的接口,也用于A
ctiveX文档技术。A ctiveX文档包容器程序实现该接口,ActiveX文档
对象通过该接口控制激活操作,在进行界面整合操作前给包容器发出
通知。
4. IOleInPlaceFrame,它控制包容器应用程序的主框架窗口,包
括插入菜单项形成复合菜单、控制框架的模式等。服务程序通过IOle
InPlaceFrame接口实现菜单的合并以及一些界面状态的控制。
Microsoft Visual C++ 6.0包含的MFC库(6.0版)提供了完全的Ac
tiveX文档包容器和服务程序的支持,通过AppWizard可快速生成Activ
eX文档包容器程序的框架代码,框架程序包含了所有这些接口的实现
。MFC库实现ActiveX文档包容器程序的结构如下:
1. 在CWinApp的派生类即应用类中,为支持OLE进行初始化,在Ini
tInstance成员函数中调用AfxOleInit(),对OLE系统DLL进行初始化。
2. 虽然ActiveX文档在界面特性上与嵌入对象不太一致,但MFC中
实现的ActiveX文档对象完全从嵌入对象继承过来,所以用以管理Acti
veX文档对象的COleDocObjectItem类从COleClientItem(管理嵌入对
象)派生。COleDocObjectItem类实现了新的接口IOleDocum entSite,
并从COleClientItem继承了接口 IOleClientSite和IOleInPlaceSite
的实现,接口IOleInPlaceFrame在COleDocObjectItem的内嵌成员m_pI
nPlaceFrame中实现。因此,A ctiveX文档所要求的几个接口均在COle
DocObjectItem类中实现了,而其他的类,包括CWi nApp、CDocument和
CFrameWnd的派生类不必为支持ActiveX文档而增加新的代码。
3. 如同处理嵌入对象一样,在CView派生类也需要增加一些管理
操作,比如,创建Acti veX文档、激活对象、窗口大小调整等。创建对
象可以直接调用COleClientItem::Creat eFromFile、COleClientIte
m::CreateLinkFromFile或者COleClientItem::CreateNewIt em函数
。在AppWizard生成的代码中,通过COleInsertDialog::CreateItem函
数创建文档对象,读者可以根据需要改写这段代码。
利用Visual C++的AppWizard生成包容器工程时,注意在Step 3对
话框中,选中Activ e Document Container选项,如图2所示。完成了A
ppWizard的所有步骤后,我们就得到了一个ActiveX文档包容器程序的
框架,它可以通过对话框插入任何ActiveX文档,运行结果如图3所示,
我们可以在框架代码的基础上进行改写或者增加新的代码,这里不再
一一说明。
图2 创建ActiveX文档包容器程序时AppWizard选项示意图
图3 VC新建的ActiveX文档包容器程序运行示意图
六、结束语
本文介绍了ActiveX文档的特性和结构,并简单描述了MFC库所提
供的支持,通过例子说明了实现ActiveX文档特性并不复杂。这种特性
可以使一个应用与Internet/Intranet 联系起来,也从另一方面为浏
览器提供了扩展功能,在Internet网络不断发展的今天,Act iveX文档
特性为我们的应用走进Internet/Intranet提供了捷径。(