软件发布| 专题库| 优优资讯| 苹果专区| 安卓专区| 软件下载| 首页
优优资讯 电脑教程 安卓教程 安卓攻略 苹果教程 苹果攻略 新闻资讯

Microsoft Agent技术应用

时间:2016-05-12 来源:本站整理 我要评论
  对Agent编程的方法主要有使用VB,VC等语言进行ActiveX调用,除此之外还有直接通过VC进行COM编程调用。在VB中调用Agent是最简单不过了,但由于VB程序本身存在诸多缺陷,很难在实际中应用。
 
  而在VC中,由于Agent内部完全采用了UNICODE编码,同时还要处理各种繁杂的COM接口,从而也存在一定的问题。AgentShell是建立在Agent和应用程序之间的一个外壳程序,通过它可将Agent复杂的COM接口封装起来,转变为简单的函数调用,很好的实现对Agent的控制。同时AgentShell也作为一个独立的程序,可处理英文自动朗读等功能,本文将详细介绍其实现原理。
Microsoft Agent
  (一) 原理介绍
 
  AgentShell和Agent Server的连接是通过COM调用来实现的,对于与应用程序的通信是通过WM_COPYDATA消息来实现的,下图表示出AgentShell与其它程序的关系:
 
  [ Agent Server ]
  |
  [ COM调用 ]
  |
  [ AgentShell ]
  |
  [ 消息 ]
  |
  [ 应用程序 ]
 
  将一个Agent控制加载相应的动画和语音码我们称之为“角色”,一般使用COM调用创建一个Agent角色,要经过以下几个过程:
 
  [ 初始化COM ]
  |
  [ 连接Agent COM Sever,创建Agent控制 ]
  |
  [ 注册Agent控制的消息反应器(Notify Sink) ]
  |
  [ 加载角色数据文件,创建一个角色(Character) ]
  |
  [ 设置角色的语言、初始位置以及其它属性 ]
  |
  [ 显示角色 ]
 
  AgentShell中定义以下全局变量来控制角色的属性和动作:
 
  角色的消息ID:    long g_lNotifySinkID。
  角色ID: long g_lMyAgentID。
  Agent控制指针: IAgentEx *g_pAgentEx。
  角色指针: IAgentCharacterEx *g_pMyAgent。
  角色消息反应器指针: AgentNotifySink *g_pSink。
 
  使用以上变量可很容易的调用Agent的功能,如显示角色:
 
  BOOL agentShow()
  {
  HRESULT hRes;
  long lRequestID;
  if( !g_pMyAgent)
  return FALSE;
  hRes = g_pMyAgent->Show(FALSE, &lRequestID);
  if (FAILED(hRes))
  return FALSE;
  return TRUE;
  }
 
  (二) 角色的语言处理
 
  目前Agent支持很多种语言,不仅是显示,还有语音合成和语音识辨(对于中文,目前仅支持显示)。语言又分为主语言和子语言(或为副语言),如中文的主语言为中文(LANG_CHINESE),子语言则可为简体(SUBLANG_CHINESE_SIMPLIFIED)和繁体等。AgentShell中定义两个全局变量表达角色的语种:
 
  主语言:DWORD g_nMainLang。
  子语言:DWORD g_nSubLang。
  这样程序内必须根据当前语言的不同来显示不同的信息,如程序退出时的问候信:
  首先定义不同的语言信息,可以为宏定义或资源数据:
  #define MES_GOODBYEL"Goodbye!"
  #define MES_GOODBYE_CH L"再见!"
  #define MES_GOODNIGHTL"Good night!"
  #define MES_GOODNIGHT_CH L"祝您晚安!"
 
  以下为实现退出提示代码:
 
  void Goodbye()
  {
  if( g_bAgentOK)
  {
  SYSTEMTIME time;
  agentStop();
  agentShow();
  agentPlay(L"Wave");
  GetLocalTime(&time);
  // 根据时间不同提示不同信息
  if( g_nMainLang == LANG_ENGLISH)
  {
  // 提示英文信息
  if( time.wHour < 19)
  agentSpeak(MES_GOODBYE);
  else
  agentSpeak(MES_GOODNIGHT);
  }
  else
  {
  // 提示中文信息
  if( time.wHour < 19)
  agentSpeak(MES_GOODBYE_CH);
  else
  agentSpeak(MES_GOODNIGHT_CH);
  }
  agentHide();
  // 等待若干时间
  Sleep(MAX_QUIT_TIME);
  }
  }
 
  当然以上介绍的只是一种较为简单的方法,仅在于描述这种原理。
 
  (三) 实现自动朗读英文
 
  实现自动朗读实际上是响应剪贴板消息的过程,当复制选种的文本信息时,系统自动发送WM_DRAWCLIPBOARD消息给所有剪贴板监视队列中的窗口,相应的窗口只要读取当前剪贴板内的信息进行朗读即可,具体实现如下:
 
  安装剪贴板监视:
 
  void InstallClipSpy()
  {
  g_hNextWnd = SetClipboardViewer(g_hMainWnd);
  }
 
  主窗口的回调函数中相应剪贴板消息:
 
  LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  {
  // 剪贴板窗口队列发生变化
  case WM_CHANGECBCHAIN:
  hwndRemove = (HWND)wParam; // handle of window being removed
  hwndNext = (HWND) lParam;
  if( hwndRemove == g_hNextWnd)
  {
  g_hNextWnd = hwndNext;
  }
  if( g_hNextWnd)
  {
  SendMessage(hwndNext, WM_CHANGECBCHAIN, wParam, lParam);
  }
  // 剪贴数据发生变化
  case WM_DRAWCLIPBOARD:
  // 是否自动阅读
  if( g_bEnableRead)
  {
  // 阅读剪贴板信息
  ReadClipText();
  }
  if( g_hNextWnd)
  {
  SendMessage(g_hNextWnd,WM_DRAWCLIPBOARD,wParam, lParam);
  }
  获取剪贴板信息并且朗读:
  void ReadClipText()
  {
  if( g_bAgentOK)
  {
  // 只有文本文件才朗读
  if( IsClipboardFormatAvailable(CF_TEXT))
  {
 

用户评论

(已有0条评论)
表情
注:您的评论需要经过审核才能显示哦,请文明发言!
还没有评论,快来抢沙发吧!
快速检索
0-9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z