首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Microsoft Agent COM 介面程式設計完整指南

     編輯:關於C++

前言:為什麼選擇 COM 介面?

Microsoft Agent 作為一項成熟的互動式代理技術,廣泛應用於桌面應用程式與網頁嵌入場景。它支援 C/C++、Visual Basic、Java、JScript、VBScript 等多種語言,並提供 OLE 自動化伺服器與 ActiveX 控制項兩種程式設計模型。雖然透過 MFC 或 VB 等工具呼叫 ActiveX 控制項相當便利,但這些封裝層隱藏了底層 COM 細節。若想深入掌握 COM 物件運作機制、進行精細控制或效能調優,直接使用 COM 介面程式設計是最佳途徑。本文將系統介紹 Microsoft Agent COM 介面的核心程式設計方法,包含物件建立、角色載入、命令處理、事件通知與進階技巧,並附上完整 C++ 程式碼範例。

COM 程式設計基礎回顧

COM (Component Object Model) 是 OLE 技術的基石,定義了物件間通訊的二進位標準。每個 COM 物件透過介面對外公開功能,介面本質上是一組純虛函數表,所有介面皆繼承自 IUnknown,必須實作 QueryInterface、AddRef、Release 三大核心方法。客戶端程式透過介面指標呼叫物件功能,物件生命週期由參考計數管理。標準呼叫流程為:初始化 COM 庫 → 建立物件實例 → 取得所需介面指標 → 呼叫方法 → 釋放介面與物件 → 反初始化 COM 庫。

C++ 呼叫 Microsoft Agent 核心步驟

1. 環境準備與專案設定

  • 開發工具:Visual C++ 5.0/6.0 或更新版本
  • 必要標頭與庫:AgtSvr.h、AgtSvr_i.c (可從 Microsoft Agent SDK 或 Platform SDK 取得)
  • 連結庫:ole32.lib、oleaut32.lib、uuid.lib、odbc32.lib、odbccp32.lib
  • 執行環境:已安裝 Microsoft Agent 核心元件與角色資料檔 (.acs)

2. 初始化 COM 並建立 Agent 伺服器實例

HRESULT hRes;
IAgent *pAgent = NULL;

// 1. 初始化 COM 庫
if (FAILED(OleInitialize(NULL))) return -1;

// 2. 建立 Agent Server 實例,取得 IAgent 介面
hRes = CoCreateInstance(CLSID_AgentServer, NULL, CLSCTX_SERVER,
                        IID_IAgent, (LPVOID*)&pAgent);
if (FAILED(hRes)) return -1;

CoCreateInstance 會自動啟動或連接已執行的 Agent 伺服器。當所有 Agent 物件釋放後,伺服器會自動退出。

3. 載入角色並取得 IAgentCharacter 介面

VARIANT vPath;
long lCharID = 0, lRequestID = 0;
IDispatch *pdCharacter = NULL;
IAgentCharacter *pCharacter = NULL;

VariantInit(&vPath);
vPath.vt = VT_BSTR;
vPath.bstrVal = SysAllocString(L"C:\\Windows\\Msagent\\Chars\\Merlin.acs"); // 角色路徑

// 載入角色資料
hRes = pAgent->Load(vPath, &lCharID, &lRequestID);
// 取得角色的 IDispatch 介面
hRes = pAgent->GetCharacter(lCharID, &pdCharacter);
// QueryInterface 取得 IAgentCharacter 介面
hRes = pdCharacter->QueryInterface(IID_IAgentCharacter, (LPVOID*)&pCharacter);
pdCharacter->Release(); // 釋放 IDispatch
SysFreeString(vPath.bstrVal);
VariantClear(&vPath);

4. 控制角色:顯示、移動、說話

BSTR bszSpeak = SysAllocString(L"Hello World! 歡迎使用 Microsoft Agent!");

pCharacter->Show(FALSE, &lRequestID);                    // 顯示角色
pCharacter->MoveTo(320, 240, 100, &lRequestID);          // 移動至螢幕中心
pCharacter->Speak(bszSpeak, NULL, &lRequestID);          // 說話 (第二參數可傳 WAV/LWV 檔路徑)

SysFreeString(bszSpeak);

5. 正確釋放資源

if (pCharacter) {
    pCharacter->Release();        // 釋放角色介面
    pAgent->Unload(lCharID);      // 卸載角色資料
}
pAgent->Release();                // 釋放 Agent 伺服器介面
OleUninitialize();                // 反初始化 COM

進階程式設計關鍵技巧

1. 版本相容性檢查

為確保執行環境滿足最低版本需求,應在啟動時檢查 Agent 伺服器版本:

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);

    // 比對主/次版本號 (定義於 AgtSvr.h)
    if ((pTypeLibAttr->wMajorVerNum > AGENT_VERSION_MAJOR) ||
        (pTypeLibAttr->wMajorVerNum == AGENT_VERSION_MAJOR &&
         pTypeLibAttr->wMinorVerNum >= AGENT_VERSION_MINOR))
        bValid = TRUE;

    // 釋放介面
    if (pTypeLib) { if (pTypeLibAttr) pTypeLib->ReleaseTLibAttr(pTypeLibAttr); pTypeLib->Release(); }
    if (pTypeInfo) pTypeInfo->Release();
    if (pdAgent) pdAgent->Release();
    return bValid;
}

2. 實作 IAgentNotifySink 接收事件通知

Agent 伺服器採非同步方式處理要求,完成時觸發 RequestComplete 事件;使用者透過滑鼠/麥克風發出指令時觸發 Command 事件。客戶端需實作 IAgentNotifySink 並向伺服器註冊:

// 假設 CAgentNotifySink 繼承自 IAgentNotifySink 並覆寫所需事件處理函式
CAgentNotifySink *pSink = new CAgentNotifySink();
pSink->AddRef();
long lNotifySinkID;
pAgent->Register((IUnknown*)pSink, &lNotifySinkID);

// ... 程式執行期間 ...

pAgent->Unregister(lNotifySinkID);
pSink->Release();

3. 自訂命令擴充互動功能

透過 IAgentCommands 介面可新增自訂命令至角色的右鍵選單或命令視窗:


IAgentCommands *pCommands = NULL;
pCharacter->QueryInterface(IID_IAgentCommands, (LPVOID*)&pCommands);

// 新增命令:Caption="說明", 顯示於選單, 語音指令="Help"
pCommands->Add(L"CmdHelp", L"說明", L"Help", TRUE, TRUE, &lCmdID);

// 取得命令介面進一步設定屬性
IAgentCommand *pCmd = NULL;
pCommands->GetCommand(lCmdID, &pCmd);
pCmd->put_Visible(TRUE);
pCmd->Release();
pCommands->Release();

4. 中文語音輸出:使用 WAV/LWV 檔替代 TTS

Microsoft Agent 內建 TTS 僅支援英文。輸出中文需傳遞 WAV 或 LWV (含唇形同步資訊) 檔案路徑給 Speak 方法第二參數:


// 使用 WAV 檔,文字氣球顯示第一參數文字
BSTR bstrText = SysAllocString(L"你好!");
BSTR bstrWav = SysAllocString(L"C:\\Sounds\\hello.wav");
pCharacter->Speak(bstrText, bstrWav, &lRequestID);
SysFreeString(bstrText); SysFreeString(bstrWav);

// 使用 LWV 檔 (含文字與唇形資訊),第一參數可為空
BSTR bstrLwv = SysAllocString(L"C:\\Sounds\\hello.lwv");
pCharacter->Speak(NULL, bstrLwv, &lRequestID);
SysFreeString(bstrLwv);

LWV 檔可用 Microsoft Agent Linguistic Information Sound Editing Tool 由 WAV 產生,能讓角色嘴部動作與語音完美同步。

5. 其他實用 COM 介面概覽

介面主要功能
IAgentCommandWindow控制命令視窗位置、大小、可見性
IAgentSpeechInputProperties讀取語音輸入屬性 (多為唯讀)
IAgentAudioOutputProperties讀取語音輸出屬性
IAgentPropertySheet存取 Agent 伺服器屬性頁
IAgentBalloon設定文字氣球可見性、字型等

總結

本文詳細闡述了 Microsoft Agent COM 介面程式設計的完整流程:從 COM 初始化、物件建立、角色載入、基本控制,到版本檢查、事件通知、自訂命令、中文語音處理等進階主題。掌握這些核心技術,即可開發出功能豐富、互動性強的智慧型代理應用程式。建議開發者參考 Microsoft Agent SDK 文件深入探索更多介面與功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved