Microsoft Agent提供互動式動畫角色、語音合成與辨識功能。開發方式主要有:VB/VC透過ActiveX呼叫,或VC直接進行COM程式設計。VB雖簡單但缺陷多難實用;VC則需處理Unicode編碼與複雜COM介面。AgentShell作為Agent與應用程式間的外殼程式,將複雜COM介面封裝為簡單函式呼叫,並可獨立運行處理英文自動朗讀等功能。
[ Agent Server ]
|
[ COM呼叫 ]
|
[ AgentShell ]
|
[ 訊息傳遞 WM_COPYDATA ]
|
[ 應用程式 ]
long g_lNotifySinkID; // 角色訊息ID
long g_lMyAgentID; // 角色ID
IAgentEx *g_pAgentEx; // Agent控制項指標
IAgentCharacterEx *g_pMyAgent; // 角色指標
AgentNotifySink *g_pSink; // 角色訊息回應器指標
BOOL agentShow() {
HRESULT hRes;
long lRequestID;
if (!g_pMyAgent) return FALSE;
hRes = g_pMyAgent->Show(FALSE, &lRequestID);
return SUCCEEDED(hRes);
}
Agent支援多國語言(中文僅支援顯示),分主語言與子語言(如中文簡體/繁體)。AgentShell定義:
DWORD g_nMainLang; // 主語言
DWORD g_nSubLang; // 子語言
根據語言與時間動態切換提示訊息(如退出問候):
void Goodbye() {
if (g_bAgentOK) {
SYSTEMTIME time;
agentStop(); agentShow(); agentPlay(L"Wave");
GetLocalTime(&time);
if (g_nMainLang == LANG_ENGLISH) {
agentSpeak(time.wHour < 19 ? MES_GOODBYE : MES_GOODNIGHT);
} else {
agentSpeak(time.wHour < 19 ? MES_GOODBYE_CH : MES_GOODNIGHT_CH);
}
agentHide(); Sleep(MAX_QUIT_TIME);
}
}
原理:系統發送WM_DRAWCLIPBOARD通知剪貼板內容變更,監視鏈中的視窗讀取文字並朗讀。
void InstallClipSpy() {
g_hNextWnd = SetClipboardViewer(g_hMainWnd);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CHANGECBCHAIN:
hwndRemove = (HWND)wParam;
hwndNext = (HWND)lParam;
if (hwndRemove == g_hNextWnd) g_hNextWnd = hwndNext;
if (g_hNextWnd) SendMessage(hwndNext, WM_CHANGECBCHAIN, wParam, lParam);
break;
case WM_DRAWCLIPBOARD:
if (g_bEnableRead) ReadClipText();
if (g_hNextWnd) SendMessage(g_hNextWnd, WM_DRAWCLIPBOARD, wParam, lParam);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
void ReadClipText() {
if (g_bAgentOK && IsClipboardFormatAvailable(CF_TEXT)) {
OpenClipboard(g_hMainWnd);
HGLOBAL hData = GetClipboardData(CF_TEXT);
char* pszText = (char*)GlobalLock(hData);
if (pszText) agentSpeak(pszText);
GlobalUnlock(hData);
CloseClipboard();
}
}
AgentShell透過COM封裝與訊息機制,大幅簡化Agent開發複雜度,並延伸出自動朗讀等實用功能。核心在於:角色生命週期管理、多語言動態切換、剪貼板監視鏈正確維護。