没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|其它|编辑:郝浩|2004-01-20 11:30:00.000|阅读 1251 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
Microsoft Agent具有相当广泛的用途,我们既可以把它加入到普通应用程序中供本地系统使用,也可以把它嵌入到HTML文档中供Internet/Intranet使用。Microsoft
Agent支持C/C++、Visual Basic、Java、JScript和VBScript等多种编程语言,并为程序员提供了OLE自动化服务器和ActiveX控件两种编程方法,从本质上讲,这两种编程方法都属于OLE技术的范畴,都建立在COM
(Component Object Model,组件对象模型)的基础之上。利用VC++的MFC类库或VB等支持ActiveX的编程工具可以很容易地调用ActiveX控件,但是ActiveX控件把许多OLE技术的细节都隐藏起来了,如果我们想加深对一个COM对象的了解的话,则应直接使用它的COM接口来编程,从这一点出发,本文将介绍Microsoft
Agent的COM接口的基本编程方法,希望能够起到抛砖引玉的作用。
OLE编程的基础知识
早期的OLE(现称为OLE 1)首次出现在Windows 3.1中,其主要用途是生成复合型文档,使得一个应用程序的文档可以通过链连或嵌入的方式包含其它应用程序的数据(对象)。随着软件组件技术变得日益重要起来,Microsoft在OLE
1的基础上设计了OLE 2,利用它可以实现二进制级上可重用的软件组件,并且控制这些组件的版本和扩充其功能变得相当容易。由于OLE
2的体系结构被设计成为开放式的、可扩充的,所以以后不会再出现OLE
3或4。经过多年的发展,如今的OLE已经包括了OLE自动化、COM、COM+、DCOM和ActiveX等多项技术,它们是ActiveDirectory(将用于NT
5.0的一项关键技术)、OLE Messaging、DirectX 、Active Controls、ActiveX Scripting和Task
Scheduler等等多种新技术的基础,OLE已不再是Object Linking and Embedding的缩写,它变成了一个独立的单词,专门用来表示Microsoft的软件组件集成技术。
COM是OLE技术的基础,它规定了对象之间如何相互通讯,符合COM规范的对象也叫做COM对象。按照COM的规定,对象内部可以使用任何语言来编写,它们通过接口(Interface)来与外界通信。所谓接口是指对象提供的一组特定的功能调用(方法),每个对象可以有多个接口,不同的对象可以实现同一种接口,客户程序通过对象的接口指针来调用对象的功能。由于OLE规定了组件在二进制级上可重用,客户程序不能够直接访问对象内部的数据,读取或设置对象的属性也都要通过接口来进行。每一种接口都是从一个叫IUnknown接口继承而来,都必须重新实现IUnknown的三个方法:QueryInterface、AddRef和Release,客户程序调用QueryInterface可以获得对象的其它接口指针,AddRef和Release分别将对象的引用计数加一和减一,当引用计数为零时,对象就会被释放。客户程序调用COM对象的一般步骤是首先创建一个对象,然后获取需要的接口指针,调用相应的功能,最后释放接口指针和对象。
C++程序调用Microsoft Agent的基本方法
根据前面介绍的基础知识,下面我们来看看C++程序中如何调用Microsoft
Agent。
1.设置与选项
本文使用的编程工具为Visual C++ 5.0,程序为一般的Win32应用程序,为了使程序能够正确地编译连接和运行,您首先需要拥有AgtSvr.h和AgtSvr—i.c两个定义Microsoft
Agent的COM接口的文件,它们可以在Microsoft的MS Agent站点(http://www.microsoft.com/workshop/
prog/agent/)上找到,或者请下载Microsoft最新的Internet Client SDK或Platform
SDK,其次,请在Project/Settings/Link菜单中加入以下的库:ole32.lib、oleaut32.lib、uuid.lib、odbc32.lib
odbccp32.lib,最后要确保系统中安装有Microsoft Agent及动画人物数据。
2.创建Microsoft Agent对象
创建OLE对象之前需要初始化OLE,这由OleInitialize()函数来完成,如果OLE初始化不成功,那么就无法继续执行后面的代码,创建对象由CoCreateInstance()函数来完成:
if (FAILED(OleInitialize(NULL))) return -1;//初始化OLE
hRes = CoCreateInstance(CLSID—AgentServer,NULL,CLSCTX—SERVER,IID—IAgent,(LPVOID
*)&pAgent);//创建Microsoft Agent Server的实例
if (FAILED(hRes)) return -1;
CoCreateInstance()的第一个参数是对象的CLSID(类代码),Microsoft Agent
Server的CLSID为定义在AgtSvr—i.c文件中的CLSID—AgentServer,这个128位的编码唯一地标识了Agent服务器,服务器所在路径和运行参数等信息都放在系统注册表中;第二个参数一般情况下设为NULL;第三个参数用来指明对象的运行环境,如远程或本地,此处设为CLSCTX—SERVER;第四个参数指明用来与对象通信的接口的ID,这也是一个128位的编码,Agent的接口ID为IID—IAgent;第五个参数是用来接收IAgent的接口指针。
如果Microsoft Agent Server还没有在内存中运行,那么CoCreateInstance()会启动它并创建一个Agent对象,如果服务器已经运行了,则CoCreateInstance()会与之连接并创建一个Agent对象。当所有的Agent对象都被释放了后,服务器自动退出。
3.装入动画人物数据
下面的代码调用IAgent::Load()方法来装入一个动画人物的数据,由于Agent服务器在自己的内存空间中运行,所以传送的字符串变量需要用SysAllocString()来分配内存:
VariantInit(&vPath); //初始化OLE变量
vPath.vt = VT—BSTR; //指明变量类型为Unicode的字符串
vPath.bstrVal=SysAllocString(kpwszCharacter);
//kpwszCharacter为动画人物数据的存放路径
hRes = pAgent->Load(vPath,&lCharID,&lRequestID);
//装入数据,人物ID在lCharID中返回
hRes = pAgent->GetCharacter(lCharID,&pdCharacter);
//获取lCharID的IDispatch接口指针调用IDispatch::QueryInterface()方法可以得到
//IAgentCharacter的接口指针:
hRes = pdCharacter->QueryInterface(IID—IAgentCharacter, (LPVOID *)&pCharacter);
pdCharacter->Release(); //释放IDispath
通过IAgentCharacter接口就可以调用动画人物支持的各种方法了:
hRes = pCharacter->Show(FALSE, &lRequestID);//显示动画人物
hRes = pCharacter->MoveTo(320,240,100,&lRequestID); //移动动画人物到屏幕中央
bszSpeak = SysAllocString(L"Hello World!"); //分配字符串
hRes = pCharacter->Speak(bszSpeak, NULL, &lRequestID); //让动画人物说话
SysFreeString(bszSpeak); //释放字符串所占内存
4.释放对象
程序在退出之前需要把创建的Agent对象释放:
if (pCharacter) {
pCharacter->Release(); //释放IAgentCharacter接口
pAgent->Unload(lCharID); //卸载动画人物数据
}
pAgent->Release(); //释放Agent对象
VariantClear(&vPath); //清除OLE变量
进一步的编程要点
前面介绍的是调用Microsoft Agent服务器最基本的一些步骤,为了完成比较实际的任务,客户程序还应根据自己的情况考虑下面的一些编程要点。
1.检查Agent Server的版本
OLE要求组件或对象具有向后兼容性,高版本对象支持低版本对象的所有接口和属性,这样可以很方便地进行组件升级。客户程序通常应检查对象的版本,只有系统中安装的对象的版本号高于或等于所期望的版本号时才能调用对象。下面的IsValidAgentVersion()函数检查Microsoft
Agent的版本号,并将它与定义在AgtSvr.h文件中的版本号相比较:
BOOL IsValidAgentVersion(IAgent *pAgent) {
IDispatch *pdAgent = NULL;
ITypeInfo *pTypeInfo = NULL;
ITypeLib *pTypeLib = NULL;
TLIBATTR *pTypeLibAttr = NULL;
BOOL bValid = FALSE;
UINT uiIndex;
pAgent->QueryInterface(IID—IDispatch, (LPVOID *)&pdAgent);
pdAgent->GetTypeInfo(0, 0, &pTypeInfo); //取得类型信息
pTypeInfo->GetContainingTypeLib(&pTypeLib, &uiIndex);//取得类型库
pTypeLib->GetLibAttr(&pTypeLibAttr); //取得类型库中的属性
if ((pTypeLibAttr->wMajorVerNum > AGENT—VERSION—MAJOR) ||((pTypeLibAttr->wMajorVerNum
== AGENT—VERSION—MAJOR) &&(pTypeLibAttr->wMinorVerNum >= AGENT—VERSION—MINOR)))
bValid = TRUE; //期望的版本号定义在AgtSvr.h文件中
if (pTypeLib) {
if (pTypeLibAttr) pTypeLib->ReleaseTLibAttr(pTypeLibAttr);
pTypeLib->Release(); }
if (pTypeInfo) pTypeInfo->Release();
if (pdAgent) pdAgent->Release();
return bValid;}
2.实现IAgentNotifySink接口
为了能够处理用户的输入,了解Agent对象的状态,客户程序应实现IAgentNotifySink接口来接收Agent对象的事件。IAgentNotifySink的声明和缺省实现可以在Platform
SDK或Internet Clinet SDK中的Notify.h和Notify.cpp中找到,客户程序应根据需要修改某些事件的处理函数
。下面的代码向Agent对象注册IAgentNotifySink接口,其中AgentNotifySink是从IAgentNotifySink继承而来:
pSink = new AgentNotifySink;
pSink->AddRef(); //增加引用计数
hRes = pAgent->Register((IUnknown *)pSink, &lNotifySinkID);//进行注册
...
if (pSink) {
pAgent->Unregister(lNotifySinkID); //注销IAgentNotifySink接口
pSink->Release(); }
客户程序最感兴趣的两个事件是RequestComplete和Command。Agent服务器采用异步方式来处理客户程序的各种请求,这样客户程序可以在请求服务的同时进行自己的工作,当服务器完成一项请求时就会激发RequestComplete事件,客户程序可以判断是哪一项请求已经结束,并做相应的处理。Command事件是当用户使用鼠标或麦克风向动画人物发出命令时激发的,客户程序可以通过IAgentUserInput接口来了解命令的具体信息。
3.自定义命令
Agent服务器为每个动画人物都提供了一些缺省的命令,这些命令出现在关联菜单或命令窗口中,客户程序可以通过IAgentCommands接口添加自定义命令。
为了得到IAgentCommands的接口指针,应使用参数IID—IAgentCommands来调用IAgentCharacter::QueryInterface(),IAgentCommands的Add()或Insert()方法可以加入自定义命令,同时设置Caption、Visible和Voice属性,指明该命令是否显示出来,显示在关联菜单中还是在命令窗口中。
Agent服务器为每个命令赋予一个ID值,客户程序可以使用这个ID值调用IAgentCommands::GetCommand()方法,得到每个命令的IAgentCommand接口指针,从而对单个命令的各种属性进行调整。
4. WAV文件代替语音合成
Microsoft Agent目前只支持英语的语音合成功能,要输出中文时只能用WAV文件来代替。如果给IAgentCharacter::Speak()方法的第二个参数传递一个WAV文件的路径,那么Agent服务器自动播放这个WAV文件,并在文字气球中显示出第一个参数中包含的文字,如果给第二个参数传递一个带音节信息的LWV文件的路径,则不需要在第一个参数中提供文字,因为LWV文件中包含有文字信息。当使用LWV文件时,动画人物的嘴部动作能与输出的语音保持一致,所以在可能的情况应该尽量使用LWV文件,这种格式的文件可用Microsoft
Agent Linguistic Information Sound Editing Tool编辑WAV文件来生成。
5.其它一些COM接口
除了前面提到的接口外,Agent服务器还有其它一些COM接口。IAgentCommandWindow允许客户程序访问或设置命令窗口的属性,包括位置、大小和是否可见。IAgentSpeechInputProperties允许客户程序访问语音输入功能的属性,其中大部分属性都是只读的。IAgentAudioOutputProperties允许客户程序读取语音输出功能的部分属性。IAg
entPropertySheet允许客户程序访问或设置Agent服务器的属性表。IAgentBalloon允许客户程序访问文字气球的属性,可以设置少数属性,如是否可见和字体名称。关于这些接口的具体定义和用途请参考Microsoft
Agent的帮助文档。
总 结
Microsoft Agent是一项较新的技术,它属于OLE的范畴,涉及较深的编程理论,本文所介绍的只是从OLE自动化服务角度出发的最基本的使用方法,感兴趣的读者可以参考Microsoft
Press出版的《Inside OLE》(第二版)一书来进一步了解OLE编程的知识,并参加Microsoft的Agent新闻讨论组(新闻服务器为msnews.microsoft.com,讨论组为microsoft.public.msagent)。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号