Microsoft Agent技术应用

2016-02-19 12:13 6 1 收藏

生活已是百般艰难,为何不努力一点。下面图老师就给大家分享Microsoft Agent技术应用,希望可以让热爱学习的朋友们体会到设计的小小的乐趣。

【 tulaoshi.com - 编程语言 】

Microsoft Agent技术应用
                                      --AgentShell的实现原理介绍

[摘要]
    本文介绍了如何应用Agent的以及AgentShell的实现原理和几个重要的技术处理。

[关键词]
    Agent,COM,角色,语音识别,语音合成。

    对Agent编程的方法主要有使用VB,VC等语言进行ActiveX调用,除此之外还有直接通过VC进行COM
编程调用。在VB中调用Agent是最简单不过了,但由于VB程序本身存在诸多缺陷,很难在实际中应用。
而在VC中,由于Agent内部完全采用了UNICODE编码,同时还要处理各种繁杂的COM接口,从而也存在一
定的问题。AgentShell是建立在Agent和应用程序之间的一个外壳程序,通过它可将Agent复杂的COM接
口封装起来,转变为简单的函数调用,很好的实现对Agent的控制。同时AgentShell也作为一个独立的程
序,可处理英文自动朗读等功能,本文将详细介绍其实现原理。
    (一) 原理介绍
    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))
          {

来源:https://www.tulaoshi.com/n/20160219/1600250.html

延伸阅读
子分类技术的原理:要先取得原先Window Procedure所在的地址,将之记录起来,接着设定所有的消息都先转到我们所写的消息处理过程上来,我们过滤传过来的消息,寻找特定的消息进行处理,其余的送回系统,由系统决定如何处理。等到我们不需要再处理这些特定的消息时,便取消消息的截取,即中止子分类过程。它一般需要三个过程:开始截取,消息...
进入信息和网络化的时代以来,计算机正在我们的工作和生活中扮演着日益重要的角色。越来越多的用户通过计算机来获取信息、处理信息,同时将自己最重要的信息以数据文件的形式保存在计算机中。有人形容网络好比是一片最自由的天地,在这里你可以尽情发挥自己的想象力,打造一片完全属于自己的小世界,但是如果我们的网络中缺少最起码的...
----Internet无疑是一种重要的信息传播媒体,随着其迅猛发展,将会有越来越多的企业、商团、政府机关、学校、科研机构需要在Internet上建立自己的网点。建设一个网点,硬件上需要专用服务器、集线器、路由器,租用数据通信用的专线,软件上需要安装网络操作系统和Internet服务器(www、FTP和gopher服务器),更为重要的是,需要编写大量的I...
标签: ASP
      ASP从发布至今已经7年了,使用ASP技术已经相当成熟,自从微软推出了ASP.NET之后就逐渐停止了对ASP版本的更新。但是由于有很多人仍然习惯使用ASP来开发网站,所以,再次我将以一个简单的例子来说明在ASP中如何使用Cache。 简单的说使用Cache基本原理是,把经常需要且获得代价昂贵的数据在内存中持续保存一定时间,...
标签: Web开发
AJAX全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。 Ajax技术是目前在浏览器中通过JavaScript脚本可以使用的所有技术的集合。Ajax并没有创造出某种具体的新技术,它所使用的所有技术都是在很多年前就已经存在了,然而Ajax以一种崭新的方式来使用所有的这些技术,使得...

经验教程

275

收藏

60
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部