• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Microsoft Agent的COM接口編程

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    Microsoft Agent(關于這項技術的詳細介紹請參考《中國計算機報》1997 年46期的《Microsoft Agent技術談》一文)具有相當廣泛的用途,我們既可以 把它加入到普通應用程序中供本地系統使用,也可以把它嵌入到HTML文檔中供 Internet/Intranet使用。Microsoft Age
      Microsoft Agent(關于這項技術的詳細介紹請參考《中國計算機報》1997
    年46期的《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規定了組件在二進制級
    上可重調用對象的功能。由于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 odbclearcase/" target="_blank" >ccp32.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變量
      VariantClear(&vPath); //清除OLE變量

       進一步的編程要點
      前面介紹的是調用Microsoft Agent服務器最基本的一些步驟,為了完
    成比較實際的任務,客戶程序還應根據自己的情況考慮下面的一些編程要點。

       1.檢查Agent Server的版本
      OLE要求組件或對象具有向后兼容性,高版本對象支持低版本對象的所
    有接口和屬性,這樣可以很方便地進行組件升級??蛻舫绦蛲ǔ獧z查對象
    的版本,只有系統中安裝的對象的版本號高于或等于所期望的版本號時才能
    調用對象。下面的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的聲明
    和缺省實現可以在Platfo事件。IAgentNotifySink的聲明和缺省實現可以
    在Platform SDK或Internet Clinet SDK中的Notify.h和Notify.cp
    p中找到,客戶程序應根據需要修改某些事件的處理函數。下面的代碼向
    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.自定義命令事件。
        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); //注銷IA
    gentNotifySink接口
      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文件時,動畫人物的嘴部動作能與輸出的語音保持一致
    WV文件時,動畫人物的嘴部動作能與輸出的語音保持一致,所以在可能的情況
    應該盡量使用LWV文件,這種格式的文件可用Microsoft Agent Linguistic  
    Information Sound Editing Tool編輯WAV文件來生成。

       5.其它一些COM接口
      除了前面提到的接口外,Agent服務器還有其它一些COM接口。
    IAgentCommandWindow允許客戶程序訪問或設置命令窗口的屬性,包括位置、
    大小和是否可見。IAgentSpeechInputProperties允許客戶程序訪問語音輸入
    功能的屬性,其中大部分屬性都是只讀的。IAgentAudioOutputProperties允
    許客戶程序讀取語音輸出功能的部分屬性。IAgentPropertySheet允許客戶程
    序訪問或設置Agent服務器的屬性表。IAgentBalloon允許客戶程序訪問文字
    氣球的屬性,可以設置少數屬性,如是否可見和字體名稱。關于這些接口的具
    體定義和用途請參考Microsoft Agent的幫助文檔。

       總 結
      Microsoft Agent是一項較新的技術,它屬于OLE的范疇,涉及較深的編程
    理論,本文所介紹的只是從OLE自動化服務角度出發的最基本的使用方法,感
    興趣的讀者可以參考Microsoft Press出版的《Inside OLE》(第二版)一書來進
    一步了解OLE編程的知識,并參加Microsoft的Agent新聞討論組(新聞服務器為
    msnews.microsoft.com,討論組

    ip       0     IP       # Internet protocol
    icmp     1     ICMP     # Internet control message protocol
    ggp      3     GGP      # Gateway-gateway protocol
    tcp      6     TCP      # Transmission control protocol
    egp      8     EGP      # Exterior gateway protocol
    pup      12    PUP      # PARC universal packet protocol
    udp      17    UDP      # User datagram protocol
    hmp      20    HMP      # Host monitoring protocol
    xns-idp  22    XNS-IDP  # Xerox NS IDP
    rdp      27    RDP      # "reliable datagram" protocol
    rvd      66    RVD      # MIT remote virtual disk

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>